SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1))));
    }
 
+   /*
+    * Create the temporary "diff" table.
+    *
+    * Temporarily switch out of the SECURITY_RESTRICTED_OPERATION context,
+    * because you cannot create temp tables in SRO context.  For extra
+    * paranoia, add the composite type column only after switching back to
+    * SRO context.
+    */
    SetUserIdAndSecContext(relowner,
                           save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
+   resetStringInfo(&querybuf);
+   appendStringInfo(&querybuf,
+                    "CREATE TEMP TABLE %s (tid pg_catalog.tid)",
+                    diffname);
+   if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
+       elog(ERROR, "SPI_exec failed: %s", querybuf.data);
+   SetUserIdAndSecContext(relowner,
+                          save_sec_context | SECURITY_RESTRICTED_OPERATION);
+   resetStringInfo(&querybuf);
+   appendStringInfo(&querybuf,
+                    "ALTER TABLE %s ADD COLUMN newdata %s",
+                    diffname, tempname);
+   if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
+       elog(ERROR, "SPI_exec failed: %s", querybuf.data);
 
-   /* Start building the query for creating the diff table. */
+   /* Start building the query for populating the diff table. */
    resetStringInfo(&querybuf);
    appendStringInfo(&querybuf,
-                    "CREATE TEMP TABLE %s AS "
+                    "INSERT INTO %s "
                     "SELECT mv.ctid AS tid, newdata.*::%s AS newdata "
                     "FROM %s mv FULL JOIN %s newdata ON (",
                     diffname, tempname, matviewname, tempname);
                           "WHERE newdata.* IS NULL OR mv.* IS NULL "
                           "ORDER BY tid");
 
-   /* Create the temporary "diff" table. */
-   if (SPI_exec(querybuf.data, 0) != SPI_OK_UTILITY)
+   /* Populate the temporary "diff" table. */
+   if (SPI_exec(querybuf.data, 0) != SPI_OK_INSERT)
        elog(ERROR, "SPI_exec failed: %s", querybuf.data);
 
-   SetUserIdAndSecContext(relowner,
-                          save_sec_context | SECURITY_RESTRICTED_OPERATION);
-
    /*
     * We have no further use for data from the "full-data" temp table, but we
     * must keep it around because its type is referenced from the diff table.