---
# Note: quote any value containing a {...} placeholder, as done throughout this
# file. YAML treats a leading `{` as the start of a flow mapping, so an unquoted
# template value fails to parse as the intended string.

# Values under lifecycle are defaults for every table. A table may override
# description, output.file.naming.template, and any partition option.
lifecycle:
  # The directory should already exist. Generated migrations are written here.
  directory: migrations/partitions

  # Used consistently when calculating partition bounds and retention.
  timezone: Etc/UTC

  # {parent_table_schema} and {parent_table_name} are resolved before {description} is used
  # by output.file.naming.template
  description:
    make: "Make partitions for {parent_table_schema}.{parent_table_name}"
    expire: "Expire partitions for {parent_table_schema}.{parent_table_name}"

  # Supported placeholders include {integer}, {integer:N}, {description},
  # {timestamp}, {epoch}, {date}, {year}, {month}, {day}, {hour}, and
  # {direction}. The direction is currently "up".
  output:
    file:
      naming:
        template: "V{integer:3}__{description}.sql"

  # Add supported `IF NOT EXISTS`, `CREATE OR REPLACE` to generated DDL.
  idempotent: true

  partition:
    # Partition names support {parent_table_schema}, {parent_table_name}, and PostgreSQL
    # to_char patterns such as YYYY, MM, DD, HH24, MI, SS, IYYY, and IW
    #https://www.postgresql.org/docs/current/functions-formatting.html#:~:text=Table%C2%A09.27.%C2%A0Template%20Patterns%20for%20Date/Time%20Formatting.
    naming:
      template: "{parent_table_schema}__{parent_table_name}__YYYY_MM"

    # Defaults to the parent table's schema when omitted. The schema and tablespace must already exist in the database.
    schema: partitions
    tablespace: pg_default

    # Used by the make phase of pgp-run-lifecycle. Any positive PostgreSQL interval is valid.
    interval: 1 month
    # NOW is the default, so this may be omitted. It only matters on a table's first
    # run: once a partition exists, its upper bound always overrides start_timestamp,
    # so generation keeps moving forward from the latest partition on later runs.
    start_timestamp: NOW
    past: 0
    future: 2

    # Create a default partition when the parent does not already have one.
    default:
      create: true
      naming:
        template: "{parent_table_schema}__{parent_table_name}__default"

    # Prevent generation of partitions older than this interval and generate
    # expiration DDL for partitions whose upper bound is at least this old.
    # With **detach_first** enabled, generated SQL detaches and then drops each
    # expired partition. **detach_only** takes precedence.
    retention:
      interval: 12 months
      detach_first: true
      detach_only: false
      detach_concurrently: true

    # When true, skip partitions whose partition bounds will overlap with another,
    # useful when the partitioning strategy is being changed e.g. from weekly to monthly,
    # which could result in overlapping partitions.
    skip_overlapping: false

    # Storage modes:
    #   override - use only these parameters (the default)
    #   inherit  - use parameters from the provided template table
    #   merge    - inherit from the template table, then apply these overrides
    storage:
      mode: override
      parameters:
        fillfactor: 90
        autovacuum_enabled: true

    index:
      naming:
        template: "{partition_name}_{index_keys}_{index_type}_idx{ordinal}"
      tablespace: pg_default

    # The generic constraint template is the fallback. Type-specific templates
    # override it. {constraint_suffix} resolves to pkey, key, fkey, check, or
    # excl. {ordinal} is empty for the first matching object.
    constraint:
      naming:
        template: "{partition_name}_{constraint_keys}_{constraint_suffix}{ordinal}"
        primary_key:
          template: "{partition_name}_pkey"
        unique_key:
          template: "{partition_name}_{constraint_keys}_key{ordinal}"
        foreign_key:
          template: "{partition_name}_{constraint_keys}_fkey{ordinal}"
        check:
          template: "{partition_name}_{constraint_keys}_check{ordinal}"
        exclusion:
          template: "{partition_name}_{constraint_keys}_excl{ordinal}"

    trigger:
      naming:
        template: "{partition_name}_{event_timing}_{trigger_event}_{trigger_function_name}{ordinal}"

  tables:
    - schema: public
      name: transactions
      idempotent: true

      # Objects present on this table but absent from the partitioned parent
      # are replicated onto new partitions. This can also be
      # CURRENT_PARTITION, LATEST_PARTITION, or DEFAULT_PARTITION.
      template:
        schema: public
        name: transactions_template

    - schema: public
      name: audit_events

      # Table-level values override lifecycle defaults.
      idempotent: false
      description:
        make: "Make weekly partitions for {parent_table_schema}_{parent_table_name}"
        expire: "Expire weekly partitions for {parent_table_schema}_{parent_table_name}"
      partition:
        naming:
          template: "{parent_table_schema}__{parent_table_name}__IYYY_IW"
        interval: 1 week
        future: 4
        retention:
          interval: 26 weeks
          detach_only: true
          detach_first: false
          detach_concurrently: false
