Skip to content

Output formats

Columnar tables, row maps, and Arrow vectors.

A Backend<T> chooses the Java result container; a Format chooses the column layout of reference and historical results. Every request, recipe, and latest() snapshot accepts a backend.

Backends (Backend<T>) ​

Every request, recipe, and Subscription#latest(Backend) method has an overload that returns a Table by default, and an overload that takes a Backend<T> and returns T:

BackendReturn type TMetadataDescription
Backend.TABLE (default)TableImplements ResultMetadataViewImmutable columnar table backed by canonical little-endian Arrow buffers, decoded lazily on access.
Backend.ROWSRowsResultImplements ResultMetadataViewUnmodifiable List<Map<String, Object>> (one map per row in column order) plus columnNames() and ResultMetadataView.
Backend.IPC_STREAMbyte[]In Arrow IPC schema metadataRaw Arrow IPC stream bytes (also returned by engine.requestRaw(RequestSpec)).
Backend.IPC_FILEbyte[]In Arrow IPC schema metadataRaw Arrow IPC file bytes (also returned by engine.requestIpcFile(RequestSpec)).
Backend.map(base, name, mapper)TPreserved if T keeps itCustom backend derived by applying mapper to base on the callback executor.
ArrowBackends.vectorSchemaRoot(allocator)VectorSchemaRootIn root.getSchema().getCustomMetadata()Apache Arrow Java VectorSchemaRoot (io.github.underloam:xbbg-jdk17); caller must close() the returned root.
java
import io.github.underloam.xbbg.Backend;
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.RowsResult;
import io.github.underloam.xbbg.table.Table;
import java.util.Map;

public class BackendsExample {
  public static void main(String[] args) {
    // Default: columnar Table
    Table table = Xbbg.await(Blp.bdp("AAPL US Equity", "PX_LAST"));
    System.out.println("Table rows: " + table.numRows());

    // Row maps with metadata
    RowsResult rows = Xbbg.await(Blp.bdp("AAPL US Equity", "PX_LAST", Backend.ROWS));
    for (Map<String, Object> row : rows) {
      System.out.println(row.get("value"));
    }

    // Raw Arrow IPC stream bytes
    byte[] ipcStream = Xbbg.await(Blp.bdp("AAPL US Equity", "PX_LAST", Backend.IPC_STREAM));
    System.out.println("IPC stream bytes: " + ipcStream.length);
  }
}

Working with Table, Column, and Row ​

Table ​

Table implements Iterable<Row> and ResultMetadataView:

  • Shape and schema: numRows(), numColumns(), columns(), columnNames(), hasColumn(name), findColumn(name) (Optional<Column>), column(index), and column(name) (throws IllegalArgumentException if absent).
  • Row access: row(index) returns a lightweight Row view, for (Row row : table) iterates over rows, and toRows() materializes a RowsResult.

Column and DataType ​

Each Column exposes its name(), physical type() (DataType), optional timezone() (for timestamp columns), nullable(), size(), nullCount(), and toList().

Column / Row methodApplicable DataTypesNull behavior
isNull(row) / row.isNull(col)AnyReturns true when the cell is null
get(row) / row.get(col)AnyReturns null when null; otherwise boxed Boolean, Byte/Short/Integer/Long (INT8..INT64), Short/Integer/Long/BigInteger (UINT8..UINT64), Float/Double, String, byte[], LocalDate, LocalTime, Instant (zoned timestamp), or LocalDateTime (unzoned timestamp)
getBoolean(row)BOOLThrows IllegalStateException if null
getInt(row)INT8, INT16, INT32, UINT8, UINT16, DATE32, TIME32_S, TIME32_MSThrows IllegalStateException if null
getLong(row)All integer, date, time, and timestamp typesThrows IllegalStateException if null
getFloat(row)FLOAT32, INT8, INT16, UINT8, UINT16Throws IllegalStateException if null
getDouble(row)All float and integer typesThrows IllegalStateException if null
getString(row)UTF8, LARGE_UTF8Returns null when null
getBytes(row)BINARY, LARGE_BINARY, UTF8, LARGE_UTF8Returns null when null
getLocalDate(row)DATE32, DATE64Returns null when null
getLocalTime(row)TIME32_S, TIME32_MS, TIME64_US, TIME64_NSReturns null when null
getInstant(row)TIMESTAMP_S, TIMESTAMP_MS, TIMESTAMP_US, TIMESTAMP_NSReturns null when null (unzoned timestamps are read as UTC)
getZonedDateTime(row)TIMESTAMP_*Returns null when null (uses column's timezone(), or UTC if unzoned)
getLocalDateTime(row)TIMESTAMP_*Returns null when null (wall-clock time in column's zone, or as stored if unzoned)
java
import io.github.underloam.xbbg.BdhOptions;
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Format;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.Column;
import io.github.underloam.xbbg.table.Row;
import io.github.underloam.xbbg.table.Table;
import java.util.Arrays;

public class TableIterationExample {
  public static void main(String[] args) {
    Table hist =
        Xbbg.await(
            Blp.bdh(
                "SPX Index",
                Arrays.asList("PX_LAST", "PX_VOLUME"),
                BdhOptions.builder()
                    .start("2024-01-01")
                    .end("2024-01-31")
                    .format(Format.SEMI_LONG)
                    .build()));

    // Column-oriented access (check isNull before primitive getters)
    Column dates = hist.column("date");
    Column pxLast = hist.column("PX_LAST");
    for (int i = 0; i < hist.numRows(); i++) {
      if (!pxLast.isNull(i)) {
        System.out.println(dates.getLocalDate(i) + ": " + pxLast.getDouble(i));
      }
    }

    // Row-oriented iteration
    for (Row row : hist) {
      Double close = row.isNull("PX_LAST") ? null : row.getDouble("PX_LAST");
      System.out.println(row.getLocalDate("date") + " -> " + close);
    }
  }
}

Apache Arrow Java interop (io.github.underloam:xbbg-jdk17) ​

With io.github.underloam:xbbg-jdk17 and org.apache.arrow:arrow-vector plus an Arrow BufferAllocator (RootAllocator from arrow-memory-unsafe or arrow-memory-netty) on the class path, you can either receive VectorSchemaRoot directly as a request/recipe/delivery backend or convert an existing Table:

  • ArrowBackends.vectorSchemaRoot(BufferAllocator): reads the native Arrow IPC stream directly into a VectorSchemaRoot, transferring the first batch's buffers without copying and preserving schema custom metadata.
  • ArrowTables.toVectorSchemaRoot(Table, BufferAllocator): copies an xbbg Table into a new VectorSchemaRoot with the same column names, Arrow types, timestamp time zones, nullability, and schema metadata.

WARNING

The caller owns every VectorSchemaRoot returned by ArrowBackends.vectorSchemaRoot(...) or ArrowTables.toVectorSchemaRoot(...) and must close it before closing the BufferAllocator. On Java 17+, start the JVM with --add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED.

java
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.jdk17.ArrowBackends;
import io.github.underloam.xbbg.jdk17.ArrowTables;
import io.github.underloam.xbbg.table.Table;
import org.apache.arrow.memory.BufferAllocator;
import org.apache.arrow.memory.RootAllocator;
import org.apache.arrow.vector.VectorSchemaRoot;

public class ArrowInteropExample {
  public static void main(String[] args) {
    try (BufferAllocator allocator = new RootAllocator()) {
      // 1. Stream directly into a VectorSchemaRoot via ArrowBackends
      try (VectorSchemaRoot root =
          Xbbg.await(
              Blp.bdp(
                  "IBM US Equity",
                  "PX_LAST",
                  ArrowBackends.vectorSchemaRoot(allocator)))) {
        System.out.println("Direct VectorSchemaRoot rows: " + root.getRowCount());
        System.out.println("Schema: " + root.getSchema());
      }

      // 2. Or convert an existing xbbg Table into a VectorSchemaRoot
      Table table = Xbbg.await(Blp.bdp("IBM US Equity", "PX_LAST"));
      try (VectorSchemaRoot converted = ArrowTables.toVectorSchemaRoot(table, allocator)) {
        System.out.println("Converted VectorSchemaRoot rows: " + converted.getRowCount());
      }
    }
  }
}

Request formats (Format) ​

Format controls the column layout of reference-data (bdp) and historical-data (bdh) results:

Enum constantWire valueColumns
Format.LONG (default)"long"ticker, field, value (all values formatted as text)
Format.LONG_TYPED"long_typed"ticker, field, value_f64, value_i64, value_str, value_bool, value_date, value_ts, value_time
Format.LONG_WITH_METADATA"long_metadata"ticker, field, value, dtype (text values plus each value's Arrow type name)
Format.SEMI_LONG"semi_long"One row per security (bdp) or per security and date (bdh), one typed column per requested field

With EngineConfig.Builder#keyColumn(KeyColumn.SECURITY), the first column is named security instead of the deprecated ticker default. Only bdp and bdh accept non-default formats; other operations reject format with BlpValidationException.

Result metadata (ResultMetadataView and ResultMetadata) ​

Both Table and RowsResult implement ResultMetadataView, which exposes decoded response diagnostics directly on the result (and via result.resultMetadata()):

MethodReturn typePresent when
metadata()Map<String, String>Always (raw Arrow schema metadata)
bloombergRequestId()Optional<String>The result came from a single Bloomberg request and the SDK assigned a support RequestId
bloombergRequestIds()List<String>Sorted, deduplicated list of all SDK-assigned RequestIds contributing to the result
eidData()Optional<Map<String, List<Integer>>>returnEids(true) was set on bdp, bds, bdh, bdib, or bdtick
delayed()Optional<Map<String, DelayedDataInfo>>onDelayed(...) (DelayedPolicy.WARN or IGNORE) was set and the delayed check ran
securityErrors()Optional<Map<String, BloombergMetadataError>>includeSecurityErrors(true) was set and Bloomberg reported security errors
fieldExceptions()Optional<Map<String, List<BloombergFieldException>>>Bloomberg reported per-security field exceptions
fieldErrors()Optional<Map<String, BloombergFieldError>>fieldInfo, bflds, or FieldInfoRequest asked for field IDs that Bloomberg refused
typeMisses()Optional<Map<String, Long>>Non-null values could not be converted to their column's declared Arrow type
java
import io.github.underloam.xbbg.BdpOptions;
import io.github.underloam.xbbg.Blp;
import io.github.underloam.xbbg.DelayedPolicy;
import io.github.underloam.xbbg.Xbbg;
import io.github.underloam.xbbg.table.BloombergFieldException;
import io.github.underloam.xbbg.table.DelayedDataInfo;
import io.github.underloam.xbbg.table.Table;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class ResultMetadataExample {
  public static void main(String[] args) {
    Table ref =
        Xbbg.await(
            Blp.bdp(
                Arrays.asList("VOD LN Equity", "AAPL US Equity"),
                Arrays.asList("PX_LAST"),
                BdpOptions.builder()
                    .returnEids(true)
                    .includeSecurityErrors(true)
                    .onDelayed(DelayedPolicy.IGNORE)
                    .build()));

    System.out.println("Support RequestIds: " + ref.bloombergRequestIds());

    ref.eidData()
        .ifPresent(
            eids -> System.out.println("Entitlement IDs: " + eids));

    ref.delayed()
        .ifPresent(
            (Map<String, DelayedDataInfo> delayedMap) ->
                delayedMap.forEach(
                    (sec, info) ->
                        System.out.println(
                            sec
                                + " delayed="
                                + info.delayed()
                                + " minutes="
                                + info.delayMinutes())));

    ref.fieldExceptions()
        .ifPresent(
            (Map<String, List<BloombergFieldException>> exceptions) ->
                System.out.println("Field exceptions: " + exceptions));
  }
}

Date and datetime inputs (Dates) ​

Option builders and recipe methods accept dates and datetimes either as strings or as java.time.TemporalAccessor instances (LocalDate, LocalDateTime, OffsetDateTime, ZonedDateTime, Instant). The public Dates utility applies the same formatting rules:

MethodAccepted inputsOutput
Dates.formatDate(String)"YYYYMMDD", "YYYY-MM-DD", "YYYY/MM/DD", or ISO 8601 datetime"YYYYMMDD" (or null when null/blank)
Dates.formatDate(TemporalAccessor)LocalDate, LocalDateTime, OffsetDateTime, ZonedDateTime (uses own calendar date), Instant (uses UTC date)"YYYYMMDD"
Dates.formatDate(java.util.Date)java.util.Date (UTC date) or java.sql.Date (local date)"YYYYMMDD"
Dates.formatDateTime(String)"YYYYMMDD" (-> YYYY-MM-DDT00:00:00) or ISO 8601 datetime string (keeps naive strings naive)ISO 8601 string
Dates.formatDateTime(TemporalAccessor)LocalDateTime (naive), LocalDate (T00:00:00), ZonedDateTime / OffsetDateTime (with offset), Instant (UTC with .SSS and Z)ISO 8601 string
Dates.formatDateTime(java.util.Date)java.util.DateUTC ISO 8601 string with milliseconds

Month/day-ambiguous strings such as "01/17/2024" throw IllegalArgumentException before any request is sent.

Quickstart

First requests, options, and error handling.

Streaming

Scalar Ticks, ArrowSubscription tables, and DeliveryStream envelopes.

Recipes

Analytics workflows returning Table or any Backend<T>.

API Surface

Every class in io.github.underloam.xbbg.table and io.github.underloam.xbbg.jdk17.

xbbg is independent open-source software and is not affiliated with, endorsed by, sponsored by, or approved by Bloomberg Finance L.P.