Skip to content
Snippets Groups Projects
Unverified Commit b53969ac authored by Fabian Franz's avatar Fabian Franz Committed by GitHub
Browse files

Merge pull request #7 from LionsAd/issue-3280696--use-default-on-null

Issue #3280696: Use DEFAULT ON NULL instead of the defaults trigger
parents 3313ce89 a1ec29e2
No related branches found
No related tags found
No related merge requests found
......@@ -163,57 +163,6 @@ EOF;
return $key;
}
/**
* Emulates mysql default column behaviour.
*
* Eg. insert into table (col1) values (null).
* If col1 has default in mysql you have the default inserted instead of null.
* On oracle you have null inserted. So we need a trigger to intercept this
* condition and substitute null with default. This happens on MySQL only
* inserting not updating.
*/
public function rebuildDefaultsTrigger($table) {
$schema = $this->tableSchema($this->connection->prefixTables('{' . $table . '}'));
$oname = $this->oid($table, FALSE, FALSE);
$trigger = 'create or replace trigger ' . $this->oid('TRG_' . $table . '_DEFS', TRUE) .
' before insert on ' . $this->oid($table, TRUE) .
' for each row begin /* defs trigger */ if inserting then ';
$serial_oname = $this->connection->queryOracle("select field_name from table(identifier.get_serial(?,?))", array($table, $schema))->fetchColumn();
$serial_oname = $serial_oname ? $serial_oname : "^NNC^";
$stmt = $this->connection->queryOracle(
"select /*+ALL_ROWS*/ column_name,
data_default
from all_tab_columns
where column_name != ?
and owner= nvl(user,?)
and table_name= ?
and data_default is not null
",
array($serial_oname, $schema, $oname)
);
$def = FALSE;
while ($row = $stmt->fetchObject()) {
$def = TRUE;
$trigger .=
'if :NEW."' . $row->column_name . '" is null or to_char(:NEW."' . $row->column_name . '") = \'' . ORACLE_EMPTY_STRING_REPLACER . '\'
then :NEW."' . $row->column_name . '":= ' . $row->data_default . ';
end if;
';
}
if (!$def) {
$trigger .= ' null; ';
}
$trigger .= 'end if; end;';
$this->connection->query($trigger, [], ['allow_delimiter_in_query' => TRUE]);
}
/**
* {@inheritdoc}
*/
......@@ -225,7 +174,6 @@ EOF;
foreach ($statements as $statement) {
$this->connection->query($statement, [], ['allow_delimiter_in_query' => TRUE]);
}
$this->rebuildDefaultsTrigger($name);
$this->resetLongIdentifiers();
$this->resetTableInformation($name);
}
......@@ -309,10 +257,6 @@ EOF;
$oname = $this->oid($name);
$sql = $oname . ' ' . $spec['oracle_type'];
if (isset($spec['type']) && $spec['type'] == 'serial') {
unset($spec['not null']);
}
if ($spec['oracle_type'] == 'VARCHAR2') {
$sql .= '(' . (!empty($spec['length']) ? $spec['length'] : ORACLE_MAX_VARCHAR2_LENGTH) . ' CHAR)';
}
......@@ -328,15 +272,20 @@ EOF;
$sql .= '(' . $spec['precision'] . ', ' . $spec['scale'] . ')';
}
// DEFAULT ON NULL implies NOT NULL.
$on_null = '';
if (!empty($spec['not null'])) {
$on_null = 'ON NULL ';
}
if (isset($spec['identity'])) {
$sql .= " GENERATED BY DEFAULT ON NULL AS IDENTITY";
$sql .= " GENERATED BY DEFAULT " . $on_null . "AS IDENTITY";
}
elseif (isset($spec['default'])) {
$default = is_string($spec['default']) ? $this->connection->quote($this->connection->cleanupArgValue($spec['default'])) : $spec['default'];
$sql .= " default {$default}";
$sql .= " DEFAULT " . $on_null . "{$default}";
}
if (!empty($spec['not null'])) {
elseif (!empty($spec['not null'])) {
$sql .= ' NOT NULL';
}
......@@ -687,15 +636,18 @@ EOF;
* {@inheritdoc}
*/
public function fieldSetDefault($table, $field, $default) {
$on_null = '';
if (is_null($default)) {
$default = 'NULL';
}
else {
// @todo There might be cases where the column is not actually NOT NULL,
// but there is no way to know without looking at the Drupal schema.
$on_null = 'ON NULL ';
$default = is_string($default) ? $this->connection->quote($this->connection->cleanupArgValue($default)) : $default;
}
$this->connection->query('ALTER TABLE ' . $this->oid($table, TRUE) . ' MODIFY (' . $this->oid($field) . ' DEFAULT ' . $default . ' )');
$this->rebuildDefaultsTrigger($table);
$this->connection->query('ALTER TABLE ' . $this->oid($table, TRUE) . ' MODIFY (' . $this->oid($field) . ' DEFAULT ' . $on_null . $default . ' )');
}
/**
......@@ -703,7 +655,6 @@ EOF;
*/
public function fieldSetNoDefault($table, $field) {
$this->connection->query('ALTER TABLE ' . $this->oid($table, TRUE) . ' MODIFY (' . $this->oid($field) . ' DEFAULT NULL)');
$this->rebuildDefaultsTrigger($table);
}
/**
......@@ -1216,7 +1167,6 @@ EOF;
$this->resetLongIdentifiers();
$this->resetTableInformation($cache_table);
$this->rebuildDefaultsTrigger($trigger_table);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment