Skip to content
This repository has been archived by the owner on Jan 2, 2025. It is now read-only.

Commit

Permalink
Fix Oracle for ORA-01408: such column list already indexed (#325)
Browse files Browse the repository at this point in the history
  • Loading branch information
mondrake authored Jul 1, 2023
1 parent ba16cba commit ab339fb
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 17 deletions.
49 changes: 34 additions & 15 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,54 @@ env:
SIMPLETEST_BASE_URL: "http://localhost:8080"
PHPUNIT_SKIP_CLASS: '[
"Drupal\\KernelTests\\Core\\Cache\\ApcuBackendTest",
"Drupal\\Tests\\file\\Functional\\FileAddPermissionsUpdateTest",
"Drupal\\Tests\\file\\Functional\\DownloadTest"
"Drupal\\Tests\\file\\Functional\\FileAddPermissionsUpdateTest"
]'

jobs:

#################################

sqlite-pdo:
name: "SQLite with PDO"
oracle-oci8:
name: "Oracle on Oci8"
runs-on: ubuntu-20.04
env:
DRUDBAL_ENV: "dbal/sqlite/file"
DBAL_URL: "sqlite://localhost/sites/drudbal.sqlite"
SIMPLETEST_DB: "dbal://localhost/sites/drudbal.sqlite?module=drudbal&dbal_driver=pdo_sqlite"
DRUDBAL_ENV: "dbal/oci8"
DBAL_URL: "oci8://DRUDBAL:[email protected]:1521/XE"
SIMPLETEST_DB: "dbal://DRUDBAL:[email protected]:1521/XE?module=drudbal&dbal_driver=oci8#dru"

services:
oracle:
image: gvenzl/oracle-xe:slim-faststart
env:
ORACLE_PASSWORD: oracle
ports:
- "1521:1521"
options: >-
--health-cmd healthcheck.sh
--health-interval 20s
--health-timeout 10s
--health-retries 10
strategy:
fail-fast: false
matrix:
php-version:
# - "8.1"
- "8.2"
test-args:
- "--group Database"
# - "--group Entity"
# - "--group Cache,Config"
# - "--group field,Field"
# - "--group file"
# - "--group views"
# - "--group Entity"
# - "--group Cache,Config"
# - "--group field,Field"
# - "--group file"
# - "--group views"

steps:
- name: Install PHP
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "none"
extensions: "oci8"
ini-values: "zend.assertions=1"

- name: Checkout Drupal
Expand All @@ -62,21 +74,28 @@ jobs:
- name: Install Composer dependencies
run: |
composer install --no-progress --ansi
composer config --no-plugins allow-plugins.composer/package-versions-deprecated true
- name: Composer require DruDbal from local staging
run: |
git -C drudbal_staging checkout -b test-run-branch
composer config repositories.test-run '{"type": "path", "url": "drudbal_staging", "options": {"symlink": false}}'
composer require "mondrake/drudbal:dev-test-run-branch" --no-progress --ansi
- name: Install Drupal
- name: Create Oracle schema
run: |
cp modules/contrib/drudbal/tests/github/install_* .
php install_oracle.php
- name: Install Drupal
continue-on-error: true
run: |
vendor/bin/drush site-install standard --db-url=$SIMPLETEST_DB -y
vendor/bin/drush runserver localhost:8080 --default-server=localhost:8080 &
sleep 1s
sleep 5s
- name: Report installation
continue-on-error: true
run: |
php install_report.php
vendor/bin/drush core:status
Expand Down
4 changes: 4 additions & 0 deletions src/Driver/Database/dbal/DbalExtension/AbstractExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ public function delegateQueryExceptionProcess($query, array $args, array $option
throw new \LogicException("Method " . __METHOD__ . "() not implemented.");
}

public function delegateClientExecuteStatementException(DbalDriverException $e, string $sql, string $message): void {
throw new \LogicException("Method " . __METHOD__ . "() not implemented.");
}

/**
* {@inheritdoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ public function delegateMapConditionOperator(string $operator): ?array;
public function delegateNextId(int $existing_id = 0): int;

/**
* Handles a DbalExceptions thrown by Connection::query().
* Handles DbalExceptions thrown by Drupal's Connection::query().
*
* @param string $query
* A string containing the failing SQL query.
Expand All @@ -307,6 +307,18 @@ public function delegateNextId(int $existing_id = 0): int;
*/
public function delegateQueryExceptionProcess($query, array $args, array $options, $message, DbalDriverException|DatabaseExceptionWrapper $e);

/**
* Handles exceptions thrown by DBAL Connection::executeStatement().
*
* @param DbalDriverException $e
* The exception thrown by query().
* @param string $sql
* A string containing the failing SQL query.
* @param string $message
* The message to be re-thrown.
*/
public function delegateClientExecuteStatementException(DbalDriverException $e, string $sql, string $message): void;

/**
* Runs a limited-range query.
*
Expand Down
14 changes: 14 additions & 0 deletions src/Driver/Database/dbal/DbalExtension/Oci8Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,20 @@ public function delegateQueryExceptionProcess($query, array $args, array $option
}
}

public function delegateClientExecuteStatementException(DbalDriverException $e, string $sql, string $message): void {
switch ($e->getCode()) {
// ORA-01408: such column list already indexed.
case 1408:
// Just return, Oracle detected that an index with same columns exists
// already
return;

default:
throw new DatabaseExceptionWrapper($message, $e->getCode(), $e);

}
}

/**
* {@inheritdoc}
*/
Expand Down
13 changes: 13 additions & 0 deletions src/Driver/Database/dbal/ExceptionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,17 @@ public function handleExecutionException(\Exception $exception, StatementInterfa
$this->connection->getDbalExtension()->delegateQueryExceptionProcess($query_string, $arguments, $options, $message, $exception);
}

/**
* Handles exceptions thrown by DBAL Connection::executeStatement().
*
* @param DbalDriverException $exception
* The exception thrown by executeStatement().
* @param string $sql
* A string containing the failing SQL query.
*/
public function handleClientExecuteStatementException(DbalDriverException $exception, string $sql): void {
$message = $exception->getMessage() . ": " . $sql . ";";
$this->connection->getDbalExtension()->delegateClientExecuteStatementException($exception, $sql, $message);
}

}
10 changes: 9 additions & 1 deletion src/Driver/Database/dbal/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Drupal\drudbal\Driver\Database\dbal;

use Doctrine\DBAL\Exception as DbalException;
use Doctrine\DBAL\Exception\DriverException as DbalDriverException;
use Doctrine\DBAL\Platforms\AbstractPlatform as DbalAbstractPlatform;
use Doctrine\DBAL\Schema\AbstractSchemaManager as DbalAbstractSchemaManager;
use Doctrine\DBAL\Schema\Column as DbalColumn;
Expand Down Expand Up @@ -884,7 +885,14 @@ private function dbalExecuteSchemaChange(DbalSchema $to_schema) {
if ($this->dbalExtension->getDebugging()) {
dump($sql);
}
$this->connection()->getDbalConnection()->executeStatement($sql);
try {
$this->connection()->getDbalConnection()->executeStatement($sql);
}
catch (DbalDriverException $e) {
$exceptionHandler = $this->connection()->exceptionHandler();
assert($exceptionHandler instanceOf ExceptionHandler);
$exceptionHandler->handleClientExecuteStatementException($e, $sql);
}
}
$this->dbalSetCurrentSchema($to_schema);
return TRUE;
Expand Down

0 comments on commit ab339fb

Please sign in to comment.