risingwavelabs/risingwave · error

The upstream table name must contain schema name prefix, e.g

Error message

The upstream table name must contain schema name prefix, e.g. 'public.table'

What it means

After parsing succeeds lexically, `parse_postgres_cdc_external_table_name` requires exactly 2 parts — schema and table. A 1-part name ('users') or 3+-part name ('db.public.users') is rejected because the Postgres CDC source needs the schema prefix to resolve the replication slot's table and build the Debezium topic name.

Source

Thrown at src/frontend/src/handler/create_table.rs:1185

                _ => current.push(ch),
            }
        }
    }

    if in_quote || current.is_empty() {
        return Err(anyhow!(
            "Invalid Postgres CDC table name '{}'. Expected 'schema.table'.",
            external_table_name
        )
        .into());
    }
    parts.push(current);

    if let [schema_name, table_name] = parts.as_slice() {
        Ok((schema_name.clone(), table_name.clone()))
    } else {
        Err(
            anyhow!("The upstream table name must contain schema name prefix, e.g. 'public.table'")
                .into(),
        )
    }
}

/// Reject `CREATE TABLE` when a primary-key column is filtered out of Debezium change-event
/// values via `debezium.column.exclude.list` or `debezium.column.include.list`.
///
/// Debezium's column filters only apply to the change-event **value** payload. Message keys are
/// always built from the upstream PRIMARY KEY and are not affected. If a PK column is filtered out
/// of the value, RisingWave reads NULL for that PK column from the payload, causing silent data
/// corruption: UPDATE turns into a fresh INSERT (PK mismatch with the original row) and DELETE
/// silently no-ops.
///
/// Debezium entries are regex patterns matched against the fully qualified column name
/// `<namespace>.<table>.<column>`, where namespace is `schema` for Postgres / SQL Server and
/// `database` for MySQL.
fn reject_pk_filtered_by_debezium_column_filter(

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Prefix the schema explicitly: 'public.users' instead of 'users'.
  2. Remove the database prefix — specify the database via the database_name option, not in the table name.
  3. For non-default schemas, use 'myschema.mytable'.
  4. For mixed-case or reserved-word identifiers, quote whole segments: '"MySchema"."MyTable"'.

Example fix

// before
WITH (connector = 'postgres-cdc', table_name = 'mydb.public.users')
// after
WITH (connector = 'postgres-cdc', database_name = 'mydb', table_name = 'public.users')
Defensive patterns

Strategy: validation

Validate before calling

const segs = name.split('.');
if (segs.length !== 2) throw new Error(`Postgres CDC needs exactly 'schema.table', got: ${name}`);

Type guard

const isSchemaQualified = (n) => n.split('.').length === 2 && n.split('.').every(s => s.length > 0);

Prevention

When it happens

Trigger: table_name = 'users' (no schema) or 'mydb.public.users' in a postgres-cdc CREATE TABLE option.

Common situations: Users omit 'public.' assuming a default schema; users copy a SQL Server style 3-part name; database name included out of habit from connection strings.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/1f0762ee4ea1748b. Report an issue: GitHub.