Skip to content

Foreign table columns

Generated from gateway/internal/k8s/schema.go. Edit that file and run make docs-generate; CI fails on an uncommitted difference.

IMPORT FOREIGN SCHEMA derives a table's shape from the kind's identity and its OpenAPI schema. This page lists what that produces. The extension holds the matching projection rules in extension/src/schema.rs, and unit tests on both sides assert the two agree.

Types

A column is text, bigint, boolean or timestamptz when the field's OpenAPI schema names exactly that one scalar type, and jsonb otherwise. A timestamp counts: Kubernetes spells meta.v1.Time as a reference to a date-time string. Objects, arrays, anything that may hold more than one type (IntOrString, Quantity, x-kubernetes-int-or-string), x-kubernetes-preserve-unknown-fields, and number are jsonb, which holds any value. A value that is not of its column's type reads as NULL, and an absent field is NULL rather than zero.

An extension that predates typed columns does not ask for them, and gets the types these columns had before: text for a universal or promoted column, jsonb for a top-level field. The tables below give the typed form.

Universal columns

Every kind gets these, whatever its schema, in this order. api_version, kind and metadata are the only three fields present on every Kubernetes object, which is what makes them the keys a query spanning kinds can use. namespace is omitted for cluster-scoped kinds.

Column Type Source
api_version text apiVersion
kind text kind
name text metadata.name
namespace text metadata.namespace
uid text metadata.uid
resource_version text metadata.resourceVersion
creation_timestamp timestamptz metadata.creationTimestamp
labels jsonb metadata.labels
annotations jsonb metadata.annotations
metadata jsonb metadata

Hand-mapped columns for built-in kinds whose useful fields sit deeper than the generic top-level rule reaches. A kind not listed here gets only the universal columns plus its own top-level fields.

Pod (core/v1)

Column Type Source
phase text status.phase
node text spec.nodeName

Deployment (apps/v1)

Column Type Source
replicas bigint spec.replicas
ready_replicas bigint status.readyReplicas
available_replicas bigint status.availableReplicas
updated_replicas bigint status.updatedReplicas

Top-level fields

After the universal and promoted columns, each of the kind's own top-level fields becomes a column, in sorted order, typed as described under Types. Field names are normalised to SQL identifiers, so camelCase becomes snake_case, any character outside [a-z0-9_] becomes an underscore, runs collapse, and a leading digit is prefixed. Two fields that normalise to the same name produce no column at all rather than an arbitrary winner.

These fields never become columns of their own, because a universal column already covers them: apiVersion, kind and metadata.

raw

Every table ends with a raw jsonb column holding the whole object. It is reserved before any other name is considered, so a kind with its own top-level raw field does not displace it. It is also how to read anything no column promotes, and how to write a field no column exposes.