tools/cdb2_sqlreplay/cdb2_sqlreplay.cpp
/* We can only replay if we have the full SQL, including parameters.
   That means
   1) event logged a bindings array
   2) event logged a nbindings integer, and it's 0

   If there's non-zero bindings and we don't have them, we can't replay.

   Another complication is transactions - we don't want to play one back
   until we have all the statements collected, and see a commit event.
   Anything with a cnonce logged is part of a transaction - a commit
   event will have the same cnonce.  SQL writes that are not part of
   a transaction get logged before txn log entry.  SQL in BEGIN/COMMIT
   blocks gets logged before the txn log entry as well.
   */
We can only replay if we have the full SQL, including parameters.
That means
1) event logged a bindings array
2) event logged a nbindings integer, and it's 0

If there's non-zero bindings and we don't have them, we can't replay.

Another complication is transactions - we don't want to play one back
until we have all the statements collected, and see a commit event.
Anything with a cnonce logged is part of a transaction - a commit
event will have the same cnonce.  SQL writes that are not part of
a transaction get logged before txn log entry.  SQL in BEGIN/COMMIT
blocks gets logged before the txn log entry as well.
We can only replay if we have the full SQL including parameters . That means 1 ) event logged a bindings array 2 ) event logged a nbindings integer and it ' s 0 If there ' s non - zero bindings and we don ' t have them we can ' t replay . Another complication is transactions - we don ' t want to play one back until we have all the statements collected and see a commit event . Anything with a cnonce logged is part of a transaction - a commit event will have the same cnonce . SQL writes that are not part of a transaction get logged before txn log entry . SQL in BEGIN / COMMIT blocks gets logged before the txn log entry as well .
void handle_sql(cdb2_hndl_tp *db, cson_value *event_val) {
    int rc;
    if (!is_replayable(event_val)) {
        cson_free_value(event_val);
        return;
    }
    const char *cnonce = get_strprop(event_val, "cnonce");
    if (cnonce == nullptr) { 
        replay(db, event_val);
        cson_free_value(event_val);
        return;
    }
    const char *sql = get_strprop(event_val, "sql");
    if (sql == NULL)
        return;
    if (strcmp(sql, "commit") == 0 || strcmp(sql, "rollback") == 0) {
        if (!is_part_of_transaction(cnonce)) {
            std::cerr << "Error: Commit/rollback record without cnonce in txn list (possibly already commited)"
                      << std::endl;
        } else {
            replay_transaction(db, event_val);
        }
        cson_free_value(event_val);
    } else if (strcmp(sql, "begin") == 0 || is_part_of_transaction(cnonce)) {
        add_to_transaction(event_val); 
    } else { 
        replay(db, event_val); 
        cson_free_value(event_val);
    }
}
void handle_sql ( cdb2_hndl_tp * db , cson_value * event_val ) { int rc ; if ( ! is_replayable ( event_val ) ) { cson_free_value ( event_val ) ; return ; } const char * cnonce = get_strprop ( event_val , " " ) ; if ( cnonce == nullptr ) { replay ( db , event_val ) ; cson_free_value ( event_val ) ; return ; } const char * sql = get_strprop ( event_val , " " ) ; if ( sql == NULL ) return ; if ( strcmp ( sql , " " ) == 0 || strcmp ( sql , " " ) == 0 ) { if ( ! is_part_of_transaction ( cnonce ) ) { std :: cerr << " " << std :: endl ; } else { replay_transaction ( db , event_val ) ; } cson_free_value ( event_val ) ; } else if ( strcmp ( sql , " " ) == 0 || is_part_of_transaction ( cnonce ) ) { add_to_transaction ( event_val ) ; } else { replay ( db , event_val ) ; cson_free_value ( event_val ) ; } }
We can only replay if we have the full SQL, including parameters.
We can only replay if we have the full SQL including parameters .
// no cnonce if comdb2api -- just replay it // new entry in list, or append // normal 'sql' statement entry which are not part of a transaction // replay immediately