Exiting When the Calling Query Has Been Canceled

The processPartition() function in your User-Defined Transform Function (UDTF) or Analytic Function (UDAnF) can call Vertica::UDXObjectCancelable.isCancled() to determine if the user has canceled the query that called it. If isCanceled() returns true, the query has been canceled and your processPartition() function should exit immediately to prevent it from wasting CPU time. If your UDx is not running in Fenced Mode, Vertica cannot halt your function, and has to wait for it to finish. If it is running in fenced mode, Vertica can eventually kill the side process running it, but not until it has wasted some processing time.

How often your processPartition() function calls isCanceled() depends on how much processing it performs on each row of data. Calling isCanceled() does add some overhead to your function, so you shouldn't call it too often. For transforms that do not perform lengthy processing, you could check for cancellation every 100 or 1000 rows or so. If your processPartition() function performs extensive processing for each row, you may want to check isCanceled() every 10 or so rows.

The following code fragment shows how you could have the StringTokenizer UDTF example check whether its query has been canceled:

// The primary class for the StringTokenizer UDTF.
class StringTokenizer : public TransformFunction {
    // Called for each partition in the table. Recieves the data from
    // The source table and
    virtual void processPartition(ServerInterface &srvInterface,
                                  PartitionReader &inputReader,
                                  PartitionWriter &outputWriter) {
        try {
            // Loop through the input rows
            int rowCount = 0; // Count the number of rows processed.
            do {
                rowCount++; // Processing a new row of data
                // Check for cancelation every 100 rows.
                if (rowCount % 100 == 0) 
                {
                    if (isCanceled()) // See if query has been canceled
                    {
                        // Log cancelation
                        srvInterface.log("Got canceled!");
                        return; // Exit out of UDTF immediately.
                    }
                }
                // Rest of the function here
                .         .        .

This example checks for cancellation after processing 100 rows in the partition of data. If the query has been canceled, the example logs a message, then returns to the caller to exit the function.

Note: You need to strike a balance between adding overhead to your functions by calling isCanceled() and having your functions waste CPU time by running after their query has been canceled (usually, a rare event). For functions such as StringTokenizer which have a low overall processing cost, it usually does not make sense to test for cancellation. The cost of adding overhead to all function calls outweighs the amount of resources wasted by having the function run to completion or having its zygote process killed by Vertica on the rare occasions that its query is canceled.