[ 
https://issues.apache.org/jira/browse/DERBY-3155?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Rick Hillegas updated DERBY-3155:
---------------------------------

    Attachment: derby-3155-01-ac-grammar.diff

Attaching derby-3155-01-ac-grammar.diff. This is the first increment of work 
for implementing the MERGE statement. This patch covers the grammar and bind() 
logic. I will run tests.

Although permissions descriptors are attached at bind() time, I did not tackle 
any of the permissions logic. The GRANT/REVOKE behavior of the MERGE statement 
will have to be verified and debugged when the execution logic is written. This 
may cascade changes back into the bind() logic.

It is also possible that I have modelled the bind() structures in a way which 
will be frustrating for code-generation or execution. When I tackle 
code-generation and execution, I may need to adjust the bind() logic further.

However, at this point I think that this increment is big enough for 
submission. This is a convenient checkpoint of work on the MERGE statement.

Here is the basic model I have adopted:

1) The WHEN MATCHED ... THEN UPDATE clause is modelled by an internally 
generated UpdateNode.

2) The WHEN MATCHED ... THEN DELETE clause is modelled by an internally 
generated DeleteNode.

3) The WHEN NOT MATCHED ... THEN INSERT clause is modelled by an internally 
generated InsertNode.

4) The WHEN [ NOT ] MATCHED clauses are driven by an internally generated 
HalfOuterJoinNode which represents the following query:

    sourceTable LEFT OUTER JOIN targetTable ON searchCondition

Along the way, I had to tweak other compile-time classes. However, I believe 
that these tweaks are minor. So far, the MERGE statement has not caused a lot 
of disruption.

A valid MERGE statement currently raises the following error at the end of the 
bind phase:

ERROR 0A000: Feature not implemented: MERGE.


Touches the following files:

-------------------

M       java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj

Grammar changes, including the introduction of two new non-reserved keywords: 
MERGE and MATCHED.

-------------------

A       java/engine/org/apache/derby/impl/sql/compile/MergeNode.java
A       java/engine/org/apache/derby/impl/sql/compile/MatchingClauseNode.java

Adds two new query nodes. MergeNode is a new DMLModStatementNode parallel to 
InsertNode, UpdateNode, and DeleteNode. MatchingClauseNode is a single class 
which can represent all three variants of the WHEN [ NOT ] MATCHED clause.

-------------------

M       java/engine/org/apache/derby/impl/sql/compile/DeleteNode.java
M       java/engine/org/apache/derby/impl/sql/compile/UpdateNode.java

When we internally generate an UpdateNode for a WHEN MATCHED ... THEN UPDATE 
clause, we have to allow references to the source table on the right side of 
the SET operator. For example, in the following statement...

merge into t1
using t2
on t1.c1 = t2.c1
when matched and t1.c2 != t2.c2 then update set c2 = t2.c2;

...we allow "set c2 = t2.c2" even though the table being updated is t1, not t2. 
This means that for this case we must disable a little piece of logic which was 
deliberately nulling out the tablename in expressions on the right side of the 
SET operator.

In addition, I disabled a Sanity check which prevented us from having more than 
one table in the query which drives an UPDATE statement. This was necessary in 
order to use a left join to drive the WHEN MATCHED ... THEN UPDATE clause.

-------------------

M       java/engine/org/apache/derby/impl/sql/compile/UnionNode.java
M       java/engine/org/apache/derby/impl/sql/compile/InsertNode.java
M       java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java

Some extra book-keeping was added in order to support DEFAULT values for 
generated columns in WHEN NOT MATCHED ... THEN INSERT clauses. The handling of 
generated columns (including identity columns) is already a set of brittle 
special cases. This makes the handling more brittle and flags an area which may 
need extra testing.

-------------------

M       java/engine/org/apache/derby/impl/sql/compile/JoinNode.java

Two new methods were created in order to abstract out some bind() logic. That 
logic is now used both by ordinary left joins and by the internally generated 
left join which drives the MERGE statement.

-------------------

M       java/engine/org/apache/derby/loc/messages.xml
M       java/shared/org/apache/derby/shared/common/reference/SQLState.java

Adds 3 new messages for errors discovered at bind() time.

-------------------

M       
java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
M       
java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
A       
java/testing/org/apache/derbyTesting/functionTests/tests/lang/MergeStatementTest.java

Adds a battery of tests for the MERGE statement's bind() logic. Mostly these 
are negative tests, stressing error conditions.

                
> Support for SQL:2003 MERGE statement
> ------------------------------------
>
>                 Key: DERBY-3155
>                 URL: https://issues.apache.org/jira/browse/DERBY-3155
>             Project: Derby
>          Issue Type: Improvement
>          Components: SQL
>            Reporter: Trejkaz
>              Labels: derby_triage10_10
>         Attachments: derby-3155-01-ac-grammar.diff, MergeStatement.html
>
>
> A relatively common piece of logic in a database application is to check for 
> a row's existence and then either update or insert depending on its existence.
> SQL:2003 added a MERGE statement to perform this operation.  It looks like 
> this:
>     MERGE INTO table_name USING table_name ON (condition)
>     WHEN MATCHED THEN UPDATE SET column1 = value1 [, column2 = value2 ...]
>     WHEN NOT MATCHED THEN INSERT column1 [, column2 ...] VALUES (value1 [, 
> value2 ...]) 
> At the moment, the only workaround for this would be to write a stored 
> procedure to do the same operation, or to implement the logic client-side.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to