Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 322067

Summary: [DB] Audit mapping creates illegal SQL for XRefs
Product: [Modeling] EMF Reporter: Eike Stepper <stepper>
Component: cdo.dbAssignee: Eike Stepper <stepper>
Status: CLOSED FIXED QA Contact: Eike Stepper <stepper>
Severity: normal    
Priority: P3 CC: stefan
Version: 4.0   
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
xref testcases
none
xref testcases v2 none

Description Eike Stepper CLA 2010-08-08 04:59:13 EDT
SELECT 
  l_t.cdo_source, 
  l_t.cdo_value, 
  l_t.cdo_idx 

FROM 
  RefMultiNonContainedNPL_elements_list AS l_t, 
  RefMultiNonContainedNPL AS a_t 
  
WHERE 
  a_t.(cdo_revised=0) AND <<<<<<<<<<<<<<<<<< !!!!!!!
  a_t.cdo_id=l_t.cdo_source AND 
  a_t.cdo_version=l_t.cdo_version AND 
  cdo_value IN (2)

Resulting exception:

org.eclipse.emf.cdo.tests.config.impl.ConfigTestException: Error in Bugzilla_320690_Test.testLockRefTargets [Combined, DBStore: H2 (Reusable Folder, audit), , JVM, Native]
	at org.eclipse.emf.cdo.tests.config.impl.ConfigTest.runBare(ConfigTest.java:431)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at org.eclipse.net4j.util.tests.AbstractOMTest.run(AbstractOMTest.java:196)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at org.eclipse.emf.cdo.tests.config.impl.ConfigTestSuite$TestWrapper.runTest(ConfigTestSuite.java:126)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.eclipse.emf.cdo.util.CommitException: org.eclipse.net4j.signal.RemoteException: org.eclipse.net4j.db.DBException: org.h2.jdbc.JdbcSQLException: Syntax Fehler in SQL Befehl SELECT L_T.CDO_SOURCE, L_T.CDO_VALUE, L_T.CDO_IDX FROM REFMULTINONCONTAINEDNPL_ELEMENTS_LIST AS L_T, REFMULTINONCONTAINEDNPL AS A_T WHERE A_T.([*]CDO_REVISED=0) AND A_T.CDO_ID=L_T.CDO_SOURCE AND A_T.CDO_VERSION=L_T.CDO_VERSION AND CDO_VALUE IN (2) ; erwartet identifier
Syntax error in SQL statement SELECT L_T.CDO_SOURCE, L_T.CDO_VALUE, L_T.CDO_IDX FROM REFMULTINONCONTAINEDNPL_ELEMENTS_LIST AS L_T, REFMULTINONCONTAINEDNPL AS A_T WHERE A_T.([*]CDO_REVISED=0) AND A_T.CDO_ID=L_T.CDO_SOURCE AND A_T.CDO_VERSION=L_T.CDO_VERSION AND CDO_VALUE IN (2) ; expected identifier; SQL statement:
SELECT l_t.cdo_source, l_t.cdo_value, l_t.cdo_idx FROM RefMultiNonContainedNPL_elements_list AS l_t, RefMultiNonContainedNPL AS a_t WHERE a_t.(cdo_revised=0) AND a_t.cdo_id=l_t.cdo_source AND a_t.cdo_version=l_t.cdo_version AND cdo_value IN (2) [42001-117]
	at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commit(CDOTransactionImpl.java:927)
	at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commit(CDOTransactionImpl.java:938)
	at org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_320690_Test.testLockRefTargets(Bugzilla_320690_Test.java:67)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:592)
	at junit.framework.TestCase.runTest(TestCase.java:168)
	at org.eclipse.net4j.util.tests.AbstractOMTest.runBare(AbstractOMTest.java:150)
	at org.eclipse.emf.cdo.tests.config.impl.ConfigTest.runBare(ConfigTest.java:422)
	... 18 more
Caused by: org.eclipse.net4j.signal.RemoteException: org.eclipse.net4j.db.DBException: org.h2.jdbc.JdbcSQLException: Syntax Fehler in SQL Befehl SELECT L_T.CDO_SOURCE, L_T.CDO_VALUE, L_T.CDO_IDX FROM REFMULTINONCONTAINEDNPL_ELEMENTS_LIST AS L_T, REFMULTINONCONTAINEDNPL AS A_T WHERE A_T.([*]CDO_REVISED=0) AND A_T.CDO_ID=L_T.CDO_SOURCE AND A_T.CDO_VERSION=L_T.CDO_VERSION AND CDO_VALUE IN (2) ; erwartet identifier
Syntax error in SQL statement SELECT L_T.CDO_SOURCE, L_T.CDO_VALUE, L_T.CDO_IDX FROM REFMULTINONCONTAINEDNPL_ELEMENTS_LIST AS L_T, REFMULTINONCONTAINEDNPL AS A_T WHERE A_T.([*]CDO_REVISED=0) AND A_T.CDO_ID=L_T.CDO_SOURCE AND A_T.CDO_VERSION=L_T.CDO_VERSION AND CDO_VALUE IN (2) ; expected identifier; SQL statement:
SELECT l_t.cdo_source, l_t.cdo_value, l_t.cdo_idx FROM RefMultiNonContainedNPL_elements_list AS l_t, RefMultiNonContainedNPL AS a_t WHERE a_t.(cdo_revised=0) AND a_t.cdo_id=l_t.cdo_source AND a_t.cdo_version=l_t.cdo_version AND cdo_value IN (2) [42001-117]
	at org.eclipse.net4j.signal.RequestWithConfirmation.setRemoteException(RequestWithConfirmation.java:128)
	at org.eclipse.net4j.signal.SignalProtocol.handleRemoteException(SignalProtocol.java:520)
	at org.eclipse.net4j.signal.RemoteExceptionIndication.indicating(RemoteExceptionIndication.java:53)
	at org.eclipse.net4j.signal.Indication.doExtendedInput(Indication.java:55)
	at org.eclipse.net4j.signal.Signal.doInput(Signal.java:315)
	at org.eclipse.net4j.signal.Indication.execute(Indication.java:49)
	at org.eclipse.net4j.signal.Signal.runSync(Signal.java:240)
	at org.eclipse.net4j.signal.Signal.run(Signal.java:146)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:651)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:676)
	at java.lang.Thread.run(Thread.java:595)
Caused by: org.eclipse.net4j.db.DBException: org.h2.jdbc.JdbcSQLException: Syntax Fehler in SQL Befehl SELECT L_T.CDO_SOURCE, L_T.CDO_VALUE, L_T.CDO_IDX FROM REFMULTINONCONTAINEDNPL_ELEMENTS_LIST AS L_T, REFMULTINONCONTAINEDNPL AS A_T WHERE A_T.([*]CDO_REVISED=0) AND A_T.CDO_ID=L_T.CDO_SOURCE AND A_T.CDO_VERSION=L_T.CDO_VERSION AND CDO_VALUE IN (2) ; erwartet identifier
Syntax error in SQL statement SELECT L_T.CDO_SOURCE, L_T.CDO_VALUE, L_T.CDO_IDX FROM REFMULTINONCONTAINEDNPL_ELEMENTS_LIST AS L_T, REFMULTINONCONTAINEDNPL AS A_T WHERE A_T.([*]CDO_REVISED=0) AND A_T.CDO_ID=L_T.CDO_SOURCE AND A_T.CDO_VERSION=L_T.CDO_VERSION AND CDO_VALUE IN (2) ; expected identifier; SQL statement:
SELECT l_t.cdo_source, l_t.cdo_value, l_t.cdo_idx FROM RefMultiNonContainedNPL_elements_list AS l_t, RefMultiNonContainedNPL AS a_t WHERE a_t.(cdo_revised=0) AND a_t.cdo_id=l_t.cdo_source AND a_t.cdo_version=l_t.cdo_version AND cdo_value IN (2) [42001-117]
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractListTableMapping.queryXRefs(AbstractListTableMapping.java:559)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalClassMapping.queryXRefs(AbstractHorizontalClassMapping.java:679)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractHorizontalMappingStrategy.queryXRefs(AbstractHorizontalMappingStrategy.java:137)
	at org.eclipse.emf.cdo.server.internal.db.DBStoreAccessor.queryXRefs(DBStoreAccessor.java:282)
	at org.eclipse.emf.cdo.internal.server.TransactionCommitContext$XRefContext.getXRefs(TransactionCommitContext.java:1105)
	at org.eclipse.emf.cdo.internal.server.TransactionCommitContext.checkXRefs(TransactionCommitContext.java:784)
	at org.eclipse.emf.cdo.internal.server.TransactionCommitContext.write(TransactionCommitContext.java:322)
	at org.eclipse.emf.cdo.spi.server.InternalCommitContext$1.runLoop(InternalCommitContext.java:39)
	at org.eclipse.emf.cdo.spi.server.InternalCommitContext$1.runLoop(InternalCommitContext.java:1)
	at org.eclipse.net4j.util.om.monitor.ProgressDistributor.run(ProgressDistributor.java:96)
	at org.eclipse.emf.cdo.server.internal.net4j.protocol.CommitTransactionIndication.indicatingCommit(CommitTransactionIndication.java:308)
	at org.eclipse.emf.cdo.server.internal.net4j.protocol.CommitTransactionIndication.indicating(CommitTransactionIndication.java:166)
	at org.eclipse.emf.cdo.server.internal.net4j.protocol.CommitTransactionIndication.indicating(CommitTransactionIndication.java:120)
	at org.eclipse.net4j.signal.IndicationWithMonitoring.indicating(IndicationWithMonitoring.java:84)
	at org.eclipse.net4j.signal.IndicationWithResponse.doExtendedInput(IndicationWithResponse.java:90)
	at org.eclipse.net4j.signal.Signal.doInput(Signal.java:315)
	at org.eclipse.net4j.signal.IndicationWithResponse.execute(IndicationWithResponse.java:63)
	at org.eclipse.net4j.signal.IndicationWithMonitoring.execute(IndicationWithMonitoring.java:63)
	... 5 more
Caused by: org.h2.jdbc.JdbcSQLException: Syntax Fehler in SQL Befehl SELECT L_T.CDO_SOURCE, L_T.CDO_VALUE, L_T.CDO_IDX FROM REFMULTINONCONTAINEDNPL_ELEMENTS_LIST AS L_T, REFMULTINONCONTAINEDNPL AS A_T WHERE A_T.([*]CDO_REVISED=0) AND A_T.CDO_ID=L_T.CDO_SOURCE AND A_T.CDO_VERSION=L_T.CDO_VERSION AND CDO_VALUE IN (2) ; erwartet identifier
Syntax error in SQL statement SELECT L_T.CDO_SOURCE, L_T.CDO_VALUE, L_T.CDO_IDX FROM REFMULTINONCONTAINEDNPL_ELEMENTS_LIST AS L_T, REFMULTINONCONTAINEDNPL AS A_T WHERE A_T.([*]CDO_REVISED=0) AND A_T.CDO_ID=L_T.CDO_SOURCE AND A_T.CDO_VERSION=L_T.CDO_VERSION AND CDO_VALUE IN (2) ; expected identifier; SQL statement:
SELECT l_t.cdo_source, l_t.cdo_value, l_t.cdo_idx FROM RefMultiNonContainedNPL_elements_list AS l_t, RefMultiNonContainedNPL AS a_t WHERE a_t.(cdo_revised=0) AND a_t.cdo_id=l_t.cdo_source AND a_t.cdo_version=l_t.cdo_version AND cdo_value IN (2) [42001-117]
	at org.h2.message.Message.getSQLException(Message.java:105)
	at org.h2.message.Message.getSQLException(Message.java:116)
	at org.h2.message.Message.getSyntaxError(Message.java:141)
	at org.h2.command.Parser.readColumnIdentifier(Parser.java:2517)
	at org.h2.command.Parser.readTermObjectDot(Parser.java:2127)
	at org.h2.command.Parser.readTerm(Parser.java:2232)
	at org.h2.command.Parser.readFactor(Parser.java:1851)
	at org.h2.command.Parser.readSum(Parser.java:1838)
	at org.h2.command.Parser.readConcat(Parser.java:1811)
	at org.h2.command.Parser.readCondition(Parser.java:1682)
	at org.h2.command.Parser.readAnd(Parser.java:1662)
	at org.h2.command.Parser.readExpression(Parser.java:1654)
	at org.h2.command.Parser.parseSelectSimple(Parser.java:1611)
	at org.h2.command.Parser.parseSelectSub(Parser.java:1504)
	at org.h2.command.Parser.parseSelectUnion(Parser.java:1349)
	at org.h2.command.Parser.parseSelect(Parser.java:1337)
	at org.h2.command.Parser.parsePrepared(Parser.java:394)
	at org.h2.command.Parser.parse(Parser.java:290)
	at org.h2.command.Parser.parse(Parser.java:262)
	at org.h2.command.Parser.prepareCommand(Parser.java:234)
	at org.h2.engine.Session.prepareLocal(Session.java:415)
	at org.h2.engine.Session.prepareCommand(Session.java:376)
	at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1049)
	at org.h2.jdbc.JdbcStatement.executeQuery(JdbcStatement.java:70)
	at org.eclipse.emf.cdo.server.internal.db.mapping.horizontal.AbstractListTableMapping.queryXRefs(AbstractListTableMapping.java:529)
	... 22 more
Comment 1 Eike Stepper CLA 2010-08-08 05:14:54 EDT
I removed the superfluous parantheses.
Committed to HEAD.

But I doubt that it will also work for historical views because the table alias would need to be added to the other columns, too:

    if (timeStamp == CDORevision.UNSPECIFIED_DATE)
    {
			...
    }
    else
    {
      builder.append(CDODBSchema.ATTRIBUTES_CREATED);
      builder.append("<=");
      builder.append(timeStamp);
      builder.append(" AND ("); //$NON-NLS-1$
      builder.append(CDODBSchema.ATTRIBUTES_REVISED); <<<<<<<<<< !!!!
      builder.append("=0 OR "); //$NON-NLS-1$
      builder.append(CDODBSchema.ATTRIBUTES_REVISED); <<<<<<<<<< !!!!
      builder.append(">=");
      builder.append(timeStamp);
      builder.append(")"); //$NON-NLS-1$
    }

The same issue would then apply as well for the branching mapping strategy. What do you think, Stefan?
Comment 2 Stefan Winkler CLA 2010-08-08 07:38:13 EDT
Created attachment 176107 [details]
xref testcases
Comment 3 Stefan Winkler CLA 2010-08-08 07:47:55 EDT
To improve quality, I've created two more XRef Testcases - one for the toOne and one for the toMany case.

What I originally intended to write was:
    builder.append(mainTableWhere);
instead of
    builder.append("a_t." + mainTableWhere);
at AbstractListTableMapping line 510.

Then the brackets would have been ok. Yet, I just realized that this in turn breaks Branching, because CDO_BRANCH is ambiguous - it is part of the attribute table.

To solve this problem in general, I propose to introduce a constant ATTRIBUTE_TABLE_PREFIX (="a_t.") mapping-strategy and use it consistently in all joins.


Additional comment: 
Eike, please have a look at the "XXX fails" comments in my testcase. It seems that CDOObjectReference.getSourceReference() always returns null ?! Is this a bug?
Comment 4 Eike Stepper CLA 2010-08-08 13:01:49 EDT
> It seems that CDOObjectReference.getSourceReference() always returns null ?! Is this a bug?

Seems so. The classifierRef in the CDOObjectReference points to ecore::EReference rather than xreftest::referencer
Comment 5 Eike Stepper CLA 2010-08-08 13:16:05 EDT
Ok, I've found the problem: In QueryIndication I used ref.eClass() instead of ref.getEContainingClass().

Committed to HEAD
Comment 6 Eike Stepper CLA 2010-08-08 13:16:56 EDT
Note, your check still fails because for some reason we have two instances of the same ref. Can this relate to dynamic packages?
Comment 7 Stefan Winkler CLA 2010-08-08 15:16:39 EDT
Created attachment 176119 [details]
xref testcases v2

Yes you are right. Because of the dynamic model, the EReferences are not the same instance and EReference.equals() does not seem to be able to correctly compare them, either.

I've changed the testcase to an assertEquals for the reference names.

Now all tests are green.
Comment 8 Stefan Winkler CLA 2010-08-09 10:55:07 EDT
xref testcases committed to HEAD
Comment 9 Eike Stepper CLA 2011-06-23 03:41:33 EDT
Available in R20110608-1407