prestodb/presto · error · TypeError

no abstract type RowExpression

Error message

 no abstract type RowExpression 

What it means

to_json for shared_ptr<RowExpression> serializes based on the expression's subclass key (e.g. 'call', 'variable', 'constant', ...). When the discriminator is not among the registered values, it throws TypeError('<type> no abstract type RowExpression '). Serialization never emits unknown RowExpression subclasses, protecting the wire protocol.

Source

Thrown at presto-native-execution/presto_cpp/presto_protocol/core/presto_protocol_core.cpp:224

  }
  if (type == "constant") {
    j = *std::static_pointer_cast<ConstantExpression>(p);
    return;
  }
  if (type == "special") {
    j = *std::static_pointer_cast<SpecialFormExpression>(p);
    return;
  }
  if (type == "lambda") {
    j = *std::static_pointer_cast<LambdaDefinitionExpression>(p);
    return;
  }
  if (type == "variable") {
    j = *std::static_pointer_cast<VariableReferenceExpression>(p);
    return;
  }

  throw TypeError(type + " no abstract type RowExpression ");
}

void from_json(const json& j, std::shared_ptr<RowExpression>& p) {
  String type;
  try {
    type = p->getSubclassKey(j);
  } catch (json::parse_error& e) {
    throw ParseError(std::string(e.what()) + " RowExpression  RowExpression");
  }

  if (type == "call") {
    std::shared_ptr<CallExpression> k = std::make_shared<CallExpression>();
    j.get_to(*k);
    p = std::static_pointer_cast<RowExpression>(k);
    return;
  }
  if (type == "constant") {
    std::shared_ptr<ConstantExpression> k =

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Print the expression's subclass key to identify the unregistered type
  2. Upgrade presto-native-execution to a version whose RowExpression registry matches the coordinator
  3. Add the missing branch in to_json in presto_protocol_core.cpp for the new expression type
  4. Ensure any custom RowExpression subclass sets _type and implements getSubclassKey

Example fix

// before: special form without registry entry
expr->_type = "lambda-partial"; // not dispatched in to_json
to_json(j, expr); // -> TypeError: lambda-partial no abstract type RowExpression
// after: use a supported representation or register it
if (type == "lambda") { j = *std::static_pointer_cast<LambdaDefinitionExpression>(p); return; }
Defensive patterns

Strategy: type-guard

Validate before calling

if (!p || p->getSubclassKey(json::object()).empty()) {
  throw std::runtime_error("RowExpression has no subclass key; cannot serialize");
}

Type guard

bool isRegisteredRowExpression(const std::shared_ptr<RowExpression>& p) {
  static const std::set<std::string> known = {"call", "variable", "constant", "special", "lambda"};
  return p && known.count(p->getSubclassKey(json::object())) > 0;
}

Try / catch

try {
  to_json(j, p);
} catch (const facebook::presto::protocol::TypeError& e) {
  LOG(ERROR) << "Cannot serialize RowExpression: " << e.what();
  throw;
}

Prevention

When it happens

Trigger: Serializing a RowExpression whose getSubclassKey yields an unregistered value — a new expression type introduced upstream, a default-constructed expression with no _type, or an IR node the native protocol layer does not map.

Common situations: Coordinator (newer Presto) sending row expressions the native side predates; custom expression wrappers in tests; expressions built by native code without setting _type before round-tripping.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/33dd07eed1beb17e. Report an issue: GitHub.