/** @var int The number of rows affected as an integer */
protected $mAffectedRows = null;
- /** @var int */
- private $mInsertId = null;
/** @var float|string */
private $numericVersion = null;
/** @var string Connect string to open a PostgreSQL connection */
return pg_field_name( $res, $n );
}
- /**
- * Return the result of the last call to nextSequenceValue();
- * This must be called after nextSequenceValue().
- *
- * @return int|null
- */
public function insertId() {
- return $this->mInsertId;
+ $res = $this->query( "SELECT lastval()" );
+ $row = $this->fetchRow( $res );
+ return is_null( $row[0] ) ? null : (int)$row[0];
}
public function dataSeek( $res, $row ) {
public function selectSQLText(
$table, $vars, $conds = '', $fname = __METHOD__, $options = [], $join_conds = []
) {
+ if ( is_string( $options ) ) {
+ $options = [ $options ];
+ }
+
// 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
$forUpdateKey = array_search( 'FOR UPDATE', $options, true );
if ( $forUpdateKey !== false && $join_conds ) {
unset( $options[$forUpdateKey] );
+ $options['FOR UPDATE'] = [];
+
+ // All tables not in $join_conds are good
+ foreach ( $table as $alias => $name ) {
+ if ( is_numeric( $alias ) ) {
+ $alias = $name;
+ }
+ if ( !isset( $join_conds[$alias] ) ) {
+ $options['FOR UPDATE'][] = $alias;
+ }
+ }
foreach ( $join_conds as $table_cond => $join_cond ) {
if ( 0 === preg_match( '/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_cond[0] ) ) {
$options['FOR UPDATE'][] = $table_cond;
}
}
+
+ // Quote alias names so $this->tableName() won't mangle them
+ $options['FOR UPDATE'] = array_map( function ( $name ) use ( $table ) {
+ return isset( $table[$name] ) ? $this->addIdentifierQuotes( $name ) : $name;
+ }, $options['FOR UPDATE'] );
}
if ( isset( $options['ORDER BY'] ) && $options['ORDER BY'] == 'NULL' ) {
}
public function nextSequenceValue( $seqName ) {
- $safeseq = str_replace( "'", "''", $seqName );
- $res = $this->query( "SELECT nextval('$safeseq')" );
- $row = $this->fetchRow( $res );
- $this->mInsertId = is_null( $row[0] ) ? null : (int)$row[0];
-
- return $this->mInsertId;
+ return new NextSequenceValue;
}
/**
}
/**
- * @var string $table
- * @var string $field
+ * @param string $table
+ * @param string $field
* @return PostgresField|null
*/
public function fieldInfo( $table, $field ) {
$s = pg_escape_bytea( $conn, $s->fetch() );
}
return "'$s'";
+ } elseif ( $s instanceof NextSequenceValue ) {
+ return 'DEFAULT';
}
return "'" . pg_escape_string( $conn, $s ) . "'";