| 1891 | |
| 1892 | |
| 1893 | static bool check_prepare_result(PrepareResult prepare_result, jrd_tra* transaction, |
| 1894 | Request* request, record_param* rpb) |
| 1895 | { |
| 1896 | /************************************** |
| 1897 | * |
| 1898 | * c h e c k _ p r e p a r e _ r e s u l t |
| 1899 | * |
| 1900 | ************************************** |
| 1901 | * |
| 1902 | * Functional description |
| 1903 | * Called by VIO_modify and VIO_erase. Raise update conflict error if not in |
| 1904 | * read consistency transaction or lock error happens or if request is already |
| 1905 | * in update conflict mode. In latter case set TRA_ex_restart flag to correctly |
| 1906 | * handle request restart. |
| 1907 | * If record should be skipped, return false also. |
| 1908 | * |
| 1909 | **************************************/ |
| 1910 | if (prepare_result == PrepareResult::SUCCESS) |
| 1911 | return true; |
| 1912 | |
| 1913 | if ((rpb->rpb_stream_flags & RPB_s_skipLocked) && prepare_result == PrepareResult::SKIP_LOCKED) |
| 1914 | return false; |
| 1915 | |
| 1916 | fb_assert(prepare_result != PrepareResult::SKIP_LOCKED); |
| 1917 | |
| 1918 | Request* top_request = request->req_snapshot.m_owner; |
| 1919 | |
| 1920 | const bool restart_ready = top_request && |
| 1921 | (top_request->req_flags & req_restart_ready); |
| 1922 | |
| 1923 | // Second update conflict when request is already in update conflict mode |
| 1924 | // means we have some (indirect) UPDATE\DELETE in WHERE clause of primary |
| 1925 | // cursor. In this case all we can do is restart whole request immediately. |
| 1926 | const bool secondary = top_request && |
| 1927 | (top_request->req_flags & req_update_conflict) && |
| 1928 | (prepare_result != PrepareResult::LOCK_ERROR); |
| 1929 | |
| 1930 | if (!(transaction->tra_flags & TRA_read_consistency) || prepare_result == PrepareResult::LOCK_ERROR || |
| 1931 | secondary || !restart_ready) |
| 1932 | { |
| 1933 | if (secondary) |
| 1934 | transaction->tra_flags |= TRA_ex_restart; |
| 1935 | |
| 1936 | ERR_post(Arg::Gds(isc_deadlock) << |
| 1937 | Arg::Gds(isc_update_conflict) << |
| 1938 | Arg::Gds(isc_concurrent_transaction) << Arg::Int64(rpb->rpb_transaction_nr)); |
| 1939 | } |
| 1940 | |
| 1941 | if (top_request) |
| 1942 | { |
| 1943 | top_request->req_flags |= req_update_conflict; |
| 1944 | top_request->req_conflict_txn = rpb->rpb_transaction_nr; |
| 1945 | } |
| 1946 | return false; |
| 1947 | } |
| 1948 | |
| 1949 | |
| 1950 | bool VIO_erase(thread_db* tdbb, record_param* rpb, jrd_tra* transaction) |
no test coverage detected