}
function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
- $insertOptions = [], $selectOptions = []
+ $insertOptions = [], $selectOptions = [], $selectJoinConds = []
) {
$destTable = $this->tableName( $destTable );
- if ( !is_array( $selectOptions ) ) {
- $selectOptions = [ $selectOptions ];
- }
- list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) =
- $this->makeSelectOptions( $selectOptions );
- if ( is_array( $srcTable ) ) {
- $srcTable = implode( ',', array_map( [ $this, 'tableName' ], $srcTable ) );
- } else {
- $srcTable = $this->tableName( $srcTable );
- }
$sequenceData = $this->getSequenceData( $destTable );
if ( $sequenceData !== false &&
$val = $val . ' field' . ( $i++ );
}
- $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
- " SELECT $startOpts " . implode( ',', $varMap ) .
- " FROM $srcTable $useIndex $ignoreIndex ";
- if ( $conds != '*' ) {
- $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
- }
- $sql .= " $tailOpts";
+ $selectSql = $this->selectSQLText(
+ $srcTable,
+ array_values( $varMap ),
+ $conds,
+ $fname,
+ $selectOptions,
+ $selectJoinConds
+ );
+
+ $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ') ' . $selectSql;
if ( in_array( 'IGNORE', $insertOptions ) ) {
$this->ignoreDupValOnIndex = true;
}
public function selectField(
- $table, $var, $cond = '', $fname = __METHOD__, $options = []
+ $table, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
) {
return $this->__call( __FUNCTION__, func_get_args() );
}
public function selectFieldValues(
- $table, $var, $cond = '', $fname = __METHOD__, $options = []
+ $table, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
) {
return $this->__call( __FUNCTION__, func_get_args() );
}
public function insertSelect(
$destTable, $srcTable, $varMap, $conds,
- $fname = __METHOD__, $insertOptions = [], $selectOptions = []
+ $fname = __METHOD__, $insertOptions = [], $selectOptions = [], $selectJoinConds = []
) {
return $this->__call( __FUNCTION__, func_get_args() );
}
}
public function selectField(
- $table, $var, $cond = '', $fname = __METHOD__, $options = []
+ $table, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
) {
if ( $var === '*' ) { // sanity
throw new DBUnexpectedError( $this, "Cannot use a * field: got '$var'" );
$options['LIMIT'] = 1;
- $res = $this->select( $table, $var, $cond, $fname, $options );
+ $res = $this->select( $table, $var, $cond, $fname, $options, $join_conds );
if ( $res === false || !$this->numRows( $res ) ) {
return false;
}
public function insertSelect(
$destTable, $srcTable, $varMap, $conds,
- $fname = __METHOD__, $insertOptions = [], $selectOptions = []
+ $fname = __METHOD__, $insertOptions = [], $selectOptions = [], $selectJoinConds = []
) {
if ( $this->cliMode ) {
// For massive migrations with downtime, we don't want to select everything
$conds,
$fname,
$insertOptions,
- $selectOptions
+ $selectOptions,
+ $selectJoinConds
);
}
$fields[] = $this->fieldNameWithAlias( $sourceColumnOrSql, $dstColumn );
}
$selectOptions[] = 'FOR UPDATE';
- $res = $this->select( $srcTable, implode( ',', $fields ), $conds, $fname, $selectOptions );
+ $res = $this->select(
+ $srcTable, implode( ',', $fields ), $conds, $fname, $selectOptions, $selectJoinConds
+ );
if ( !$res ) {
return false;
}
*/
protected function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds,
$fname = __METHOD__,
- $insertOptions = [], $selectOptions = []
+ $insertOptions = [], $selectOptions = [], $selectJoinConds = []
) {
$destTable = $this->tableName( $destTable );
$insertOptions = $this->makeInsertOptions( $insertOptions );
- if ( !is_array( $selectOptions ) ) {
- $selectOptions = [ $selectOptions ];
- }
-
- list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) = $this->makeSelectOptions(
- $selectOptions );
-
- if ( is_array( $srcTable ) ) {
- $srcTable = implode( ',', array_map( [ $this, 'tableName' ], $srcTable ) );
- } else {
- $srcTable = $this->tableName( $srcTable );
- }
+ $selectSql = $this->selectSQLText(
+ $srcTable,
+ array_values( $varMap ),
+ $conds,
+ $fname,
+ $selectOptions,
+ $selectJoinConds
+ );
$sql = "INSERT $insertOptions" .
- " INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
- " SELECT $startOpts " . implode( ',', $varMap ) .
- " FROM $srcTable $useIndex $ignoreIndex ";
-
- if ( $conds != '*' ) {
- if ( is_array( $conds ) ) {
- $conds = $this->makeList( $conds, self::LIST_AND );
- }
- $sql .= " WHERE $conds";
- }
-
- $sql .= " $tailOpts";
+ " INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ') ' .
+ $selectSql;
return $this->query( $sql, $fname );
}
* @param string $fname
* @param array $insertOptions
* @param array $selectOptions
+ * @param array $selectJoinConds
* @return null|ResultWrapper
* @throws Exception
*/
public function nativeInsertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
- $insertOptions = [], $selectOptions = []
+ $insertOptions = [], $selectOptions = [], $selectJoinConds = []
) {
$this->mScrollableCursor = false;
try {
$conds,
$fname,
$insertOptions,
- $selectOptions
+ $selectOptions,
+ $selectJoinConds
);
} catch ( Exception $e ) {
$this->mScrollableCursor = true;
* @param string $fname
* @param array $insertOptions
* @param array $selectOptions
+ * @param array $selectJoinConds
* @return bool
*/
public function nativeInsertSelect(
$destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
- $insertOptions = [], $selectOptions = []
+ $insertOptions = [], $selectOptions = [], $selectJoinConds = []
) {
- $destTable = $this->tableName( $destTable );
-
if ( !is_array( $insertOptions ) ) {
$insertOptions = [ $insertOptions ];
}
$savepoint->savepoint();
}
- if ( !is_array( $selectOptions ) ) {
- $selectOptions = [ $selectOptions ];
- }
- list( $startOpts, $useIndex, $tailOpts, $ignoreIndex ) =
- $this->makeSelectOptions( $selectOptions );
- if ( is_array( $srcTable ) ) {
- $srcTable = implode( ',', array_map( [ $this, 'tableName' ], $srcTable ) );
- } else {
- $srcTable = $this->tableName( $srcTable );
- }
-
- $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
- " SELECT $startOpts " . implode( ',', $varMap ) .
- " FROM $srcTable $useIndex $ignoreIndex ";
-
- if ( $conds != '*' ) {
- $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
- }
-
- $sql .= " $tailOpts";
+ $res = parent::nativeInsertSelect( $destTable, $srcTable, $varMap, $conds, $fname,
+ $insertOptions, $selectOptions, $selectJoinConds );
- $res = (bool)$this->query( $sql, $fname, $savepoint );
if ( $savepoint ) {
$bar = pg_result_error( $this->mLastResult );
if ( $bar != false ) {
* @param string|array $cond The condition array. See IDatabase::select() for details.
* @param string $fname The function name of the caller.
* @param string|array $options The query options. See IDatabase::select() for details.
+ * @param string|array $join_conds The query join conditions. See IDatabase::select() for details.
*
* @return bool|mixed The value from the field, or false on failure.
*/
public function selectField(
- $table, $var, $cond = '', $fname = __METHOD__, $options = []
+ $table, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
);
/**
* @param string|array $cond The condition array. See IDatabase::select() for details.
* @param string $fname The function name of the caller.
* @param string|array $options The query options. See IDatabase::select() for details.
+ * @param string|array $join_conds The query join conditions. See IDatabase::select() for details.
*
* @return bool|array The values from the field, or false on failure
* @since 1.25
*/
public function selectFieldValues(
- $table, $var, $cond = '', $fname = __METHOD__, $options = []
+ $table, $var, $cond = '', $fname = __METHOD__, $options = [], $join_conds = []
);
/**
* IDatabase::insert() for details.
* @param array $selectOptions Options for the SELECT part of the query, see
* IDatabase::select() for details.
+ * @param array $selectJoinConds Join conditions for the SELECT part of the query, see
+ * IDatabase::select() for details.
*
* @return IResultWrapper
*/
public function insertSelect( $destTable, $srcTable, $varMap, $conds,
$fname = __METHOD__,
- $insertOptions = [], $selectOptions = []
+ $insertOptions = [], $selectOptions = [], $selectJoinConds = []
);
/**
protected function assertLastSql( $sqlText ) {
$this->assertEquals(
- $this->database->getLastSqls(),
- $sqlText
+ $sqlText,
+ $this->database->getLastSqls()
);
}
protected function assertLastSqlDb( $sqlText, $db ) {
- $this->assertEquals( $db->getLastSqls(), $sqlText );
+ $this->assertEquals( $sqlText, $db->getLastSqls() );
}
/**
$sql['conds'],
__METHOD__,
isset( $sql['insertOptions'] ) ? $sql['insertOptions'] : [],
- isset( $sql['selectOptions'] ) ? $sql['selectOptions'] : []
+ isset( $sql['selectOptions'] ) ? $sql['selectOptions'] : [],
+ isset( $sql['selectJoinConds'] ) ? $sql['selectJoinConds'] : []
);
$this->assertLastSql( $sqlTextNative );
$sql['conds'],
__METHOD__,
isset( $sql['insertOptions'] ) ? $sql['insertOptions'] : [],
- isset( $sql['selectOptions'] ) ? $sql['selectOptions'] : []
+ isset( $sql['selectOptions'] ) ? $sql['selectOptions'] : [],
+ isset( $sql['selectJoinConds'] ) ? $sql['selectJoinConds'] : []
);
$this->assertLastSqlDb( implode( '; ', [ $sqlSelect, $sqlInsert ] ), $dbWeb );
}
"INSERT INTO insert_table " .
"(field_insert,field) " .
"SELECT field_select,field2 " .
- "FROM select_table",
+ "FROM select_table WHERE *",
"SELECT field_select AS field_insert,field2 AS field " .
"FROM select_table WHERE * FOR UPDATE",
"INSERT INTO insert_table (field_insert,field) VALUES ('0','1')"
"FROM select_table WHERE field = '2' ORDER BY field FOR UPDATE",
"INSERT IGNORE INTO insert_table (field_insert,field) VALUES ('0','1')"
],
+ [
+ [
+ 'destTable' => 'insert_table',
+ 'srcTable' => [ 'select_table1', 'select_table2' ],
+ 'varMap' => [ 'field_insert' => 'field_select', 'field' => 'field2' ],
+ 'conds' => [ 'field' => 2 ],
+ 'selectOptions' => [ 'ORDER BY' => 'field', 'FORCE INDEX' => [ 'select_table1' => 'index1' ] ],
+ 'selectJoinConds' => [
+ 'select_table2' => [ 'LEFT JOIN', [ 'select_table1.foo = select_table2.bar' ] ],
+ ],
+ ],
+ "INSERT INTO insert_table " .
+ "(field_insert,field) " .
+ "SELECT field_select,field2 " .
+ "FROM select_table1 LEFT JOIN select_table2 ON ((select_table1.foo = select_table2.bar)) " .
+ "WHERE field = '2' " .
+ "ORDER BY field",
+ "SELECT field_select AS field_insert,field2 AS field " .
+ "FROM select_table1 LEFT JOIN select_table2 ON ((select_table1.foo = select_table2.bar)) " .
+ "WHERE field = '2' ORDER BY field FOR UPDATE",
+ "INSERT INTO insert_table (field_insert,field) VALUES ('0','1')"
+ ],
];
}