void BuildCloudDDLStatement()

in backend/schema/parser/ddl_parser.cc [3164:3448]


void BuildCloudDDLStatement(const SimpleNode* root, absl::string_view ddl_text,
                            DDLStatement* statement,
                            std::vector<std::string>* errors) {
  CheckNode(root, JJTDDL_STATEMENT);

  const SimpleNode* stmt = GetChildNode(root, 0);
  switch (stmt->getId()) {
    case JJTCREATE_DATABASE_STATEMENT:
      VisitCreateDatabaseNode(stmt, statement->mutable_create_database(),
                              errors);
      break;
    case JJTCREATE_PROTO_BUNDLE_STATEMENT: {
      CreateProtoBundle* create_proto_bundle =
          statement->mutable_create_proto_bundle();
      VisitCreateProtoBundleNode(stmt, create_proto_bundle, errors);
      break;
    }
    case JJTCREATE_TABLE_STATEMENT:
      VisitCreateTableNode(stmt, statement->mutable_create_table(), ddl_text,
                           errors);
      break;
    case JJTCREATE_INDEX_STATEMENT:
      VisitCreateIndexNode(stmt, statement->mutable_create_index(), errors);
      break;
    case JJTCREATE_PLACEMENT_STATEMENT:
      VisitCreatePlacementNode(stmt, statement->mutable_create_placement(),
                               errors);
      break;
    case JJTALTER_PLACEMENT_STATEMENT:
      VisitAlterPlacementNode(stmt, statement->mutable_alter_placement(),
                              errors);
      break;
    case JJTALTER_INDEX_STATEMENT: {
      VisitAlterIndexNode(stmt, statement->mutable_alter_index(), errors);
      break;
    }
    case JJTALTER_VECTOR_INDEX_STATEMENT: {
      VisitAlterVectorIndexNode(stmt, statement->mutable_alter_vector_index(),
                                errors);
      break;
    }
    case JJTGRANT_STATEMENT: {
      // For grant privilege statement, first child node represents privileges.
      if (GetChildNode(stmt, 0)->getId() == JJTPRIVILEGES) {
        VisitGrantPrivilegeNode(stmt, statement->mutable_grant_privilege(),
                                errors);
      } else if (GetChildNode(stmt, 0)->getId() == JJTGRANTEES) {
        // For grant membership statement, first child node represents grantees.
        VisitGrantMembershipNode(stmt, statement->mutable_grant_membership(),
                                 errors);
      } else {
        ABSL_LOG(FATAL) << "Unexpected statement: " << stmt->toString();
      }
      break;
    }
    case JJTREVOKE_STATEMENT: {
      // For revoke privilege statement, first child node represents privileges.
      if (GetChildNode(stmt, 0)->getId() == JJTPRIVILEGES) {
        VisitRevokePrivilegeNode(stmt, statement->mutable_revoke_privilege(),
                                 errors);
      } else if (GetChildNode(stmt, 0)->getId() == JJTGRANTEES) {
        // For revoke membership statement, first child node represents
        // grantees.
        VisitRevokeMembershipNode(stmt, statement->mutable_revoke_membership(),
                                  errors);
      } else {
        ABSL_LOG(FATAL) << "Unexpected statement: " << stmt->toString();
      }
      break;
    }
    case JJTRENAME_STATEMENT: {
      VisitRenameTableNode(stmt, statement->mutable_rename_table(), errors);
      break;
    }
    case JJTCREATE_SEARCH_INDEX_STATEMENT:
      VisitCreateSearchIndexNode(stmt, statement->mutable_create_search_index(),
                                 errors);
      break;
    case JJTCREATE_VECTOR_INDEX_STATEMENT:
      VisitCreateVectorIndexNode(stmt, statement->mutable_create_vector_index(),
                                 errors);
      break;
    case JJTCREATE_CHANGE_STREAM_STATEMENT:
      VisitCreateChangeStreamNode(
          stmt, statement->mutable_create_change_stream(), errors);
      break;
    case JJTCREATE_SEQUENCE_STATEMENT:
      VisitCreateSequenceNode(stmt, statement->mutable_create_sequence(),
                              errors);
      break;
    case JJTCREATE_LOCALITY_GROUP_STATEMENT:
      VisitCreateLocalityGroupNode(
          stmt, statement->mutable_create_locality_group(), errors);
      break;
    case JJTDROP_STATEMENT: {
      const SimpleNode* drop_stmt = GetChildNode(stmt, 0);
      const SimpleNode* name_node = GetFirstChildNode(stmt, JJTNAME);
      std::string name;
      if (drop_stmt->getId() == JJTLOCALITY_GROUP &&
          GetFirstChildNode(stmt, JJTDEFAULTT) != nullptr) {
        name = kDefaultLocalityGroupName;
      } else {
        name = GetQualifiedIdentifier(name_node);
      }

      switch (drop_stmt->getId()) {
        case JJTTABLE:
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_table()->set_existence_modifier(IF_EXISTS);
          }
          statement->mutable_drop_table()->set_table_name(name);
          break;
        case JJTINDEX:
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_index()->set_existence_modifier(IF_EXISTS);
          }
          statement->mutable_drop_index()->set_index_name(name);
          break;
        case JJTVECTOR_INDEX:
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_vector_index()->set_existence_modifier(
                IF_EXISTS);
          }
          statement->mutable_drop_vector_index()->set_index_name(name);
          break;
        case JJTSEARCH_INDEX:
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_search_index()->set_existence_modifier(
                IF_EXISTS);
          }
          statement->mutable_drop_search_index()->set_index_name(name);
          break;
        case JJTCHANGE_STREAM:
          statement->mutable_drop_change_stream()->set_change_stream_name(name);
          break;
        case JJTROLE:
          statement->mutable_drop_role()->set_role_name(name);
          break;
        case JJTVIEW:
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_function()->set_existence_modifier(
                IF_EXISTS);
          }
          statement->mutable_drop_function()->set_function_kind(Function::VIEW);
          statement->mutable_drop_function()->set_function_name(name);
          break;
        case JJTFUNCTION:
          if (!EmulatorFeatureFlags::instance()
                   .flags()
                   .enable_user_defined_functions) {
            errors->push_back("User defined functions are not supported.");
            return;
          }
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_function()->set_existence_modifier(
                IF_EXISTS);
          }
          statement->mutable_drop_function()->set_function_kind(
              Function::FUNCTION);
          statement->mutable_drop_function()->set_function_name(name);
          break;
        case JJTMODEL: {
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_model()->set_if_exists(true);
          }
          statement->mutable_drop_model()->set_model_name(name);
          break;
        }
        case JJTPROTO_BUNDLE:
          statement->mutable_drop_proto_bundle();  // No fields.
          break;
        case JJTSEQUENCE:
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_sequence()->set_existence_modifier(
                IF_EXISTS);
          }
          statement->mutable_drop_sequence()->set_sequence_name(name);
          break;
        case JJTSCHEMA:
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_schema()->set_if_exists(true);
          }
          statement->mutable_drop_schema()->set_schema_name(name);
          break;
        case JJTGRAPH:
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_property_graph()->set_existence_modifier(
                IF_EXISTS);
          }
          statement->mutable_drop_property_graph()->set_name(name);
          break;
        case JJTLOCALITY_GROUP:
          if (GetFirstChildNode(stmt, JJTIF_EXISTS) != nullptr) {
            statement->mutable_drop_locality_group()->set_existence_modifier(
                IF_EXISTS);
          }
          statement->mutable_drop_locality_group()->set_locality_group_name(
              name);
          break;
        case JJTPLACEMENT:
          statement->mutable_drop_placement()->set_placement_name(name);
          break;
        default:
          ABSL_LOG(FATAL) << "Unexpected object type: "
                     << GetChildNode(stmt, 0)->toString();
      }
    } break;
    case JJTALTER_PROTO_BUNDLE_STATEMENT: {
      AlterProtoBundle* alter_proto_bundle =
          statement->mutable_alter_proto_bundle();
      VisitAlterProtoBundleNode(stmt, alter_proto_bundle, errors);
      break;
    }
    case JJTALTER_DATABASE_STATEMENT:
      VisitAlterDatabaseNode(stmt, statement->mutable_alter_database(), errors);
      break;
    case JJTALTER_TABLE_STATEMENT:
      VisitAlterTableNode(stmt, ddl_text, statement, errors);
      break;
    case JJTALTER_MODEL_STATEMENT:
      VisitAlterModelNode(stmt, statement->mutable_alter_model(), errors);
      break;
    case JJTALTER_CHANGE_STREAM_STATEMENT:
      VisitAlterChangeStreamNode(stmt, statement->mutable_alter_change_stream(),
                                 errors);
      break;
    case JJTALTER_SEQUENCE_STATEMENT:
      VisitAlterSequenceNode(stmt, statement->mutable_alter_sequence(), errors);
      break;
    case JJTALTER_SCHEMA_STATEMENT:
      VisitAlterSchemaNode(stmt, statement->mutable_alter_schema(), errors);
      break;
    case JJTALTER_LOCALITY_GROUP_STATEMENT:
      VisitAlterLocalityGroupNode(
          stmt, statement->mutable_alter_locality_group(), errors);
      break;
    case JJTANALYZE_STATEMENT:
      CheckNode(stmt, JJTANALYZE_STATEMENT);
      statement->mutable_analyze();
      break;
    case JJTCREATE_OR_REPLACE_STATEMENT: {
      bool has_or_replace = (GetFirstChildNode(stmt, JJTOR_REPLACE) != nullptr);
      const SimpleNode* actual_stmt =
          GetChildNode(stmt, has_or_replace ? 1 : 0);
      switch (actual_stmt->getId()) {
        case JJTCREATE_VIEW_STATEMENT:
          VisitCreateViewNode(actual_stmt, statement->mutable_create_function(),
                              has_or_replace, ddl_text, errors);
          break;
        case JJTCREATE_MODEL_STATEMENT:
          VisitCreateModelNode(actual_stmt, statement->mutable_create_model(),
                               has_or_replace, ddl_text, errors);
          break;
        case JJTCREATE_SCHEMA_STATEMENT:
          VisitCreateSchemaNode(actual_stmt, statement->mutable_create_schema(),
                                errors);
          break;
        case JJTCREATE_FUNCTION_STATEMENT:
          VisitCreateFunctionNode(actual_stmt,
                                  statement->mutable_create_function(),
                                  has_or_replace, ddl_text, errors);
          break;
        case JJTCREATE_PROPERTY_GRAPH_STATEMENT:
          VisitCreatePropertyGraphNode(
              actual_stmt, statement->mutable_create_property_graph(),
              has_or_replace, ddl_text, errors);
          break;
        default:
          ABSL_LOG(FATAL) << "Unexpected statement: " << stmt->toString();
      }
      break;
    }
    case JJTCREATE_ROLE_STATEMENT: {
      ABSL_CHECK_EQ(stmt->jjtGetNumChildren(), 1);

      auto* create_role = statement->mutable_create_role();
      SimpleNode* name = GetChildNode(stmt, 0);
      ABSL_CHECK_EQ(name->getId(), JJTNAME);
      create_role->set_role_name(name->image());
      break;
    }
    default:
      ABSL_LOG(FATAL) << "Unexpected statement: " << stmt->toString();
  }
}