Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SAP Sybase SQL Anywhere database vendor #293

Merged
merged 14 commits into from
Nov 13, 2013

Conversation

deeky666
Copy link
Member

This PR adds the driver and DBAL for SAP Sybase SQL Anywhere databases. It distinguishes between versions 10 and below (base SQLAnywherePlatform), 11 (SQLAnywhere11Platform) and 12 (SQLAnywherer12Platform), similar to Microsoft SQL Server.
Most of the functional tests pass but there are some exceptions:

  • DataAccessTest::testFetchAllWithTypes

    Failed asserting that two strings are equal.
    --- Expected
    +++ Actual
    @@ @@
    -'2010-01-01 10:10:10'
    +'2010-01-01 10:10:10.000'
    

    The test is not aware of the datetime format string of the platform, which differs in SQL Anywhere. Therefore it fails. In SQL Anywhere a datetime is stored with second fractions by default.
    IMO I have two options here. Changing the default timestamp format for data output in the driver on every connection so that it fits Y-m-d H:i:s and changing the date format strings in the platforms or modifying the test to be aware of the platform specific datetime format.

  • MasterSlaveConnectionTest::testKeepSlaveBeginTransactionStaysOnMaster
    The test simply hangs up here and I don't exactly know why. When I change the value for insert in line 95 to some other value than 30 it perfectly works. Any help would be appreciated here.

  • ModifyLimitQueryTest::testModifyLimitQueryGroupBy

    Failed asserting that two arrays are equal.
    --- Expected
    +++ Actual
    @@ @@
    Array (
    --    0 => 1
    --    1 => 2
    ++    0 => 2
    ++    1 => 1
    )
    

    The test does not tell the SELECT statement to order the result, thus the result is not deterministic and returns the results in wrong order.
    IMO the test should be fixed so that the result is ordered correctly. Then the test will pass for SQL Anywhere.

  • TemporaryTableTest

    Exception: [Doctrine\DBAL\DBALException] An exception occurred while executing 'CREATE GLOBAL TEMPORARY TABLE temporary (id INT NOT NULL)':
    SQLSTATE [42W04] [-131] Syntaxfehler bei 'temporary' in Zeile 1
    With queries:
    SQL: 'DROP TABLE temporary' Params: 
    SQL: 'CREATE GLOBAL TEMPORARY TABLE temporary (id INT NOT NULL)'     Params: 
    SQL: 'DROP TABLE nontemporary' Params:

    The tests use the unquoted keyword "temporary" reserved by SQL Anywhere for the temporary table name to create.
    I cannot quote the name of the temporary table in the platform as the method getTemporaryTableName expects a string and not an instance of Doctrine\DBAL\Schema\Table as parameter.
    Either the tests should use a non reserved keyword as temporary table name or the temporary table name has to be quoted in the platform (but I don't know exactly how).

  • TemporaryTableTest::testDropTemporaryTableNotAutoCommitTransaction

    In an event of an error this result has one row, because of an implicit commit.
    Failed asserting that two arrays are equal.
    --- Expected
    +++ Actual
    @@ @@
    Array (
    ++    0 => Array (...)
    )
    

    The test fails because of an implicit commit during the transaction (drop temporary table) which inserts the first value. I couldn't find a solution for this problem. Seems to be the same problem as reported in DDC-1337.

  • WriteTest::testLastInsertIdNoSequenceGiven

    Failed asserting that 14 is false.

    I don't exactly know why the test expects the lastInsertId to be false here. Using the same connection for 14 inserts into a newly created autoincrement table should result in lastInsertId = 14 IMO. Is this a bug in the test? How do other vendors behave here?

I hope this addition is appreciated and any feedback/help on the above issues would be welcomed.

@doctrinebot
Copy link

Hello,

thank you for positing this Pull Request. I have automatically opened an issue on our Jira Bug Tracker for you with the details of this Pull-Request. See the Link:

http://doctrine-project.org/jira/browse/DBAL-475

use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\View;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these use statements are useless as they are already in the same namespace

@mvrhov
Copy link

mvrhov commented Mar 28, 2013

  • ModifyLimitQueryTest::testModifyLimitQueryGroupBy
    IMO you should extend the pager the same way that's done for postgresql. On the second hand the way it's done for postgresql is the proper way. So that should be default.

@deeky666
Copy link
Member Author

I don't see that the PostgreSQLPlatform makes any modifications to the limit query? It is inherited from AbstractPlatform...

@mvrhov
Copy link

mvrhov commented Mar 28, 2013

ouch this is DBAL... The exception for PostgreSQL is made in ORM.
Nonetheless the PostgreSQL is also respecting SQL standard and without the ORDER BY the order of returned values is non-deterministic. It's just a pure luck that they are returned in the same order as by default PostgreSQL returns them in the same order they are found on the disk.

@deeky666
Copy link
Member Author

Yep but if the result is non-deterministic you can't make any expectations about the order of the results. This is the problem here. Maybe other vendors order it correctly without an ORDER BY clause but then this is due to the internal SQL query optimizer rather than by the intention of the query itself. The result is simply unpredictable and SQL Anywhere sometimes seems to order them different without an ORDER BY clause.

@deeky666
Copy link
Member Author

IMO this is more an issue in the test rather than the platform. If you don't explicitly order a result you cannot make any expectations about the order afterwards.

@mvrhov
Copy link

mvrhov commented Mar 28, 2013

Yeah, I agree that the test should be fixed by adding an order by clause.

@deeky666
Copy link
Member Author

ModifyLimitQueryTest::testModifyLimitQueryGroupBy problem fixed in PR #295.

@beberlei
Copy link
Member

@deeky666 how could i verify the tests run? What are the steps to install SQL Anywhere 10-12? Would you be willing to be the champion for this platform? We cannot support this ourselves, because nobody in the team uses SAP SQL Anywhere.

Otherwise this PR is impressive work, I am very amazed by it.

@deeky666
Copy link
Member Author

@beberlei You can download the database versions 10, 11 and 12 here. You have to fill in the registration form to get the download link and product key needed for installation. During the installation you need to make sure that you install the SQL Anywhere database client and server and optionally the Sybase Central administration tool for easier testing purposes. Other components like MobiLink, QAnywhere and UltraLite are not required for testing the platform.
You can download the PHP sqlanywhere extension (native driver) here. You can either download a precompiled binary for your specific PHP version or compile it yourself using the source code and phpize.
After the installation of the database server and PHP extension you need to initially setup the doctrine test databases for functional testing. You can use the Sybase Central tool to create and start them.
I would suggest that if you need more detailed information on how to setup the databases just contact me again as it might be a little too much for this topic.
In general I would definitely like to actively maintain this platform and I am glad that you like my work!

@deeky666
Copy link
Member Author

deeky666 commented Oct 9, 2013

@beberlei rebased PR and adjusted to current abstract platform / schema. Also added version 16 of the platform. Most of the test pass but there are some problems left I'd like to discuss. Maybe we should talk soon to get this baby going :D Awaiting your feedback.


return
'LINKS=tcpip(HOST=' . $host . ';PORT=' . $port . ';DoBroadcast=Direct)' .
';SERVER=' . $server .
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "SERVER" connection parameter is only valid in SQLAnywhere 12 databases and newer[1]. Prior to version 12, the connection parameter name was "ENG" [2]. On SQLA 11, I get the following error because "SERVER" isn't recognized as valid:

SQLSTATE [08W49] [-95] Parse error: Invalid or missing keyword near 'SERVER''

However, ENG and SERVER are just the "short" versions of the parameter. The "long" version of the parameter before and after SQLA12 is "ServerName". Perhaps an easy solution is to just change this to "ServerName" so it supports all versions?

Also, I'd like to thank you for your work on this driver! :)

[1] http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.sqlanywhere.12.0.1/sachanges/sa12-deprecated-features.html
[2] http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.help.sqlanywhere.11.0.1/dbadmin_en11/servernameparameter.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out! Seems I have missed that compatibility issue. Fixed it. :)

@deeky666
Copy link
Member Author

@doctrine/team-doctrine2 okay, what else needs to be done here from your perspectives? Adjusted some more tests in PR #402 and PR #399 for this platform to work with. The only tests left failing are those where assumptions on DDL statements during transactions are done (which only works on some vendors) and @beberlei suggested that they can be ignored for now. ;)

if ($constraint instanceof Index) {
if ($constraint->isPrimary()) {
$query .= $this->getPrimaryKeyDeclarationSQL($constraint, $constraint->getQuotedName($this));
} elseif ($constraint->isUnique()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning early avoids these elseifs

beberlei added a commit that referenced this pull request Nov 13, 2013
Add SAP Sybase SQL Anywhere database vendor
@beberlei beberlei merged commit 556b624 into doctrine:master Nov 13, 2013
@beberlei
Copy link
Member

@deeky666 thank you very much for this tremendous work!

@deeky666
Copy link
Member Author

@beberlei You're welcome! :) Thanks for merging this one.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants