apache/beam · error · SqlUtil.newContextException

Table ' ' already exists

Error message

Table '%s' already exists

What it means

Thrown when CREATE EXTERNAL TABLE targets a table name that already exists in the Calcite schema and the statement lacks IF NOT EXISTS. Beam's SQL DDL parser checks pair.left.plus().getTable(pair.right) before building the table and raises a parse-context error via Calcite's RESOURCE.tableExists. It is a user-facing duplicate-definition guard, not an internal failure.

Solutions

  1. Add IF NOT EXISTS to the CREATE EXTERNAL TABLE statement
  2. Use a different table name
  3. Explicitly DROP EXTERNAL TABLE the existing table first (or use CREATE OR REPLACE semantics if supported)
  4. Inspect existing tables with schema metadata queries before running DDL

Example fix

// before
CREATE EXTERNAL TABLE orders (...) TYPE 'csv' LOCATION '/tmp/orders';
// after
CREATE EXTERNAL TABLE IF NOT EXISTS orders (...) TYPE 'csv' LOCATION '/tmp/orders';
Defensive patterns

Strategy: validation

Validate before calling

// Run before DDL
// SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'orders';
boolean exists = schema.getTableNames().stream().anyMatch(n -> n.equalsIgnoreCase("orders"));
if (exists) { /* skip create or drop first */ }

Prevention

When it happens

Trigger: Executing `CREATE EXTERNAL TABLE <name> ...` where a table (or external table) with the same simple name is already registered in the target schema and IF NOT EXISTS was not specified.

Common situations: Re-running an idempotent DDL script or pipeline bootstrap without IF NOT EXISTS; two jobs/DDL sessions creating the same external table name; migrating scripts from engines that silently replace tables.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/44ae8eda9e0918de. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/extensions/sql/src/main/java/org/apache/beam/sdk/extensions/sql/impl/parser/SqlCreateExternalTable.java:148

    }
    if (location != null) {
      writer.keyword("LOCATION");
      location.unparse(writer, 0, 0);
    }
    if (tblProperties != null) {
      writer.keyword("TBLPROPERTIES");
      tblProperties.unparse(writer, 0, 0);
    }
  }

  @Override
  public void execute(CalcitePrepare.Context context) {
    final Pair<CalciteSchema, String> pair = SqlDdlNodes.schema(context, true, name);
    if (pair.left.plus().getTable(pair.right) != null) {
      // Table exists.
      if (!ifNotExists) {
        // They did not specify IF NOT EXISTS, so give error.
        throw SqlUtil.newContextException(
            name.getParserPosition(), RESOURCE.tableExists(pair.right));
      }
      return;
    }

    Schema schema = pair.left.schema;

    BeamCalciteSchema beamCalciteSchema;
    if (schema instanceof CatalogManagerSchema) {
      TableName pathOverride = TableName.create(name.toString());
      CatalogManagerSchema catalogManagerSchema = (CatalogManagerSchema) schema;
      catalogManagerSchema.maybeRegisterProvider(pathOverride, SqlDdlNodes.getString(type));

      CatalogSchema catalogSchema = catalogManagerSchema.getCatalogSchema(pathOverride);
      beamCalciteSchema = catalogSchema.getDatabaseSchema(pathOverride);
    } else if (schema instanceof BeamCalciteSchema) {
      beamCalciteSchema = (BeamCalciteSchema) schema;
    } else {

View on GitHub (pinned to 12126d8942)