From: jenkins-bot Date: Mon, 13 Jan 2014 03:15:46 +0000 (+0000) Subject: Merge "Changed FOR UPDATE handling in Postgresql" X-Git-Tag: 1.31.0-rc.0~17271 X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=commitdiff_plain;h=da39646ddc98bce9cc1243ab217428e449b5d9ae;p=lhc%2Fweb%2Fwiklou.git Merge "Changed FOR UPDATE handling in Postgresql" --- da39646ddc98bce9cc1243ab217428e449b5d9ae diff --cc includes/db/DatabasePostgres.php index 7f0ea97635,edc8b2720c..cb671d8ddb --- a/includes/db/DatabasePostgres.php +++ b/includes/db/DatabasePostgres.php @@@ -815,10 -765,36 +815,33 @@@ __INDEXATTR__ if ( !$res ) { return null; } - foreach ( $res as $row ) { - return true; - } - return false; + return $res->numRows() > 0; } + /** + * Change the FOR UPDATE option as necessary based on the join conditions. Then pass + * to the parent function to get the actual SQL text. + * + * In Postgres when using FOR UPDATE, only the main table and tables that are inner joined + * can be locked. That means tables in an outer join cannot be FOR UPDATE locked. Trying to do + * so causes a DB error. This wrapper checks which tables can be locked and adjusts it accordingly. + */ + function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__, $options = array(), $join_conds = array() ) { + $forUpdateKey = array_search( 'FOR UPDATE', $options ); + if ( $forUpdateKey !== false && $join_conds ) { + unset( $options[$forUpdateKey] ); + + foreach ( $join_conds as $table => $join_cond ) { + if ( 0 === preg_match( '/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_cond[0] ) ) { + $options['FOR UPDATE'][] = $table; + } + } + } + + return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds ); + } + /** * INSERT wrapper, inserts an array into a table *