$this->didbegin = false;
/* If we are not in a transaction, we need to be for savepoint trickery */
if ( !$dbw->trxLevel() ) {
- $dbw->begin( "FOR SAVEPOINT" );
+ $dbw->begin( "FOR SAVEPOINT", DatabasePostgres::TRANSACTION_INTERNAL );
$this->didbegin = true;
}
}
* @param array $selectOptions
* @return bool
*/
- function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
+ function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
$insertOptions = [], $selectOptions = [] ) {
$destTable = $this->tableName( $destTable );
if ( !is_array( $selectOptions ) ) {
$selectOptions = [ $selectOptions ];
}
- list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
+ list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) =
+ $this->makeSelectOptions( $selectOptions );
if ( is_array( $srcTable ) ) {
$srcTable = implode( ',', array_map( [ &$this, 'tableName' ], $srcTable ) );
} else {
$sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
" SELECT $startOpts " . implode( ',', $varMap ) .
- " FROM $srcTable $useIndex";
+ " FROM $srcTable $useIndex $ignoreIndex ";
if ( $conds != '*' ) {
$sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
* @param string $desiredSchema
*/
function determineCoreSchema( $desiredSchema ) {
- $this->begin( __METHOD__ );
+ $this->begin( __METHOD__, self::TRANSACTION_INTERNAL );
if ( $this->schemaExists( $desiredSchema ) ) {
if ( in_array( $desiredSchema, $this->getSchemas() ) ) {
$this->mCoreSchema = $desiredSchema;
*/
function makeSelectOptions( $options ) {
$preLimitTail = $postLimitTail = '';
- $startOpts = $useIndex = '';
+ $startOpts = $useIndex = $ignoreIndex = '';
$noKeyOptions = [];
foreach ( $options as $key => $option ) {
$startOpts .= 'DISTINCT';
}
- return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail ];
+ return [ $startOpts, $useIndex, $preLimitTail, $postLimitTail, $ignoreIndex ];
}
function getDBname() {
return '(' . $this->selectSQLText( $table, $fld, $conds, null, [], $join_conds ) . ')';
}
+ /**
+ * @param string $field Field or column to cast
+ * @return string
+ * @since 1.28
+ */
+ public function buildStringCast( $field ) {
+ return $field . '::text';
+ }
+
public function getSearchEngine() {
return 'SearchPostgres';
}
*/
public function lock( $lockName, $method, $timeout = 5 ) {
$key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
- for ( $attempts = 1; $attempts <= $timeout; ++$attempts ) {
- $result = $this->query(
- "SELECT pg_try_advisory_lock($key) AS lockstatus", $method );
- $row = $this->fetchObject( $result );
- if ( $row->lockstatus === 't' ) {
- parent::lock( $lockName, $method, $timeout ); // record
- return true;
- } else {
- sleep( 1 );
- }
- }
+ $loop = new WaitConditionLoop(
+ function () use ( $lockName, $key, $timeout, $method ) {
+ $res = $this->query( "SELECT pg_try_advisory_lock($key) AS lockstatus", $method );
+ $row = $this->fetchObject( $res );
+ if ( $row->lockstatus === 't' ) {
+ parent::lock( $lockName, $method, $timeout ); // record
+ return true;
+ }
- wfDebug( __METHOD__ . " failed to acquire lock\n" );
+ return WaitConditionLoop::CONDITION_CONTINUE;
+ },
+ $timeout
+ );
- return false;
+ return ( $loop->invoke() === $loop::CONDITION_REACHED );
}
/**