You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by TomohitoNakayama <to...@basil.ocn.ne.jp> on 2005/05/28 06:51:12 UTC

about DERBY-318 (Re: DERBY-308 just be done and .... (Re: [jira] Updated: (DERBY-308) Modify dblook to support "GENERATED BY DEFAULT AS IDENTITY"))

Hello.

First of all, thank you for your kindness !

I understood the problem is that
there exists contradiction between rs.getString() and rs.wasNull()
for SYSCOLUMNS.COLUMNDEFAULT of column defined as GENERATED BY DEFAULT AS 
IDENTITY.

I will start to see pheonemanas in my environment.


I think we need to consider way to solve DERBY-318 .

page 321 at next document says..
http://publibfp.boulder.ibm.com/epubs/pdf/cs51rm.pdf

for tables, describes default value of the column.
The toString() method on the object stored in the table returns the text of 
the default value as specified in the
CREATE TABLE or ALTER TABLE statement.

for publication parameters, defines the default value of the parameter at 
the source,
and the actual value of the parameter at the target
for stored prepared statements, defines a sample value for the parameter 
used in a
CREATE STATEMENTor ALTER STATEMENT RECOMPILE statement
for optimization purposes

This is issue about table , so it is the matter how to interpret "text of 
the default value as specified in the
CREATE TABLE or ALTER TABLE statement"

//BTW, what is publication parameters ...?
// I took somethink like table ....


Best regards.

/*

         Tomohito Nakayama
         tomonaka@basil.ocn.ne.jp
         tomohito@rose.zero.ad.jp

         Naka
         http://www5.ocn.ne.jp/~tomohito/TopPage.html

*/
----- Original Message ----- 
From: "Army" <qo...@sbcglobal.net>
To: "Derby Development" <de...@db.apache.org>
Sent: Saturday, May 28, 2005 10:03 AM
Subject: Re: DERBY-308 just be done and .... (Re: [jira] Updated: 
(DERBY-308) Modify dblook to support "GENERATED BY DEFAULT AS IDENTITY")


> TomohitoNakayama wrote:
>
>> If possible , I want to work for DERBY-318 before DERBY-308 ....
>
> Tomohito,
>
> I hope you don't mind, but when I filed DERBY-318, I wasn't sure whether 
> the problem was with the DERBY-167 patch or with the server.  So, in order 
> to keep you from spending your time trying to track down a problem that 
> wasn't your fault, I started looking at this issue from the server side of 
> things--and I think I've found the problem.
>
> To make a long story short, the NPE in the server happens because of the 
> "toString()" method defined in DefaultNodeImpl.
>
> Why?  Well, I try to explain it below.  Excuse the formality of it all, 
> but I had to do it this way in order to keep it clear in my own head ;)
>
> There are several pieces that make up the puzzle.  Let me start by saying 
> what they are, and then I'll try to tie them together.
>
> ---------------
> -- The pieces.
> ---------------
>
> 1) For a column that is GENERATED BY DEFAULT, the 'defaultText' variable 
> in the corresponding DefaultNodeImpl is null.  Since 
> DefaultNodeImpl.toString() just returns defaultText, the result of 
> toString() on a DefaultNodeImpl that is GENERATED BY DEFAULT is null.
>
> 2) The underlying DataTypeDescriptor for all default columns is 
> "org.apache.derby.iapi.types.UserType".  In that class, the "isNull()" 
> method is simply written to return "(value == null)", while the 
> "getString()" method is as follows:
>
> public String getString()
> {
> if (! isNull())
> {
> return value.toString();
> }
> else
> {
> return null;
> }
> }
>
> 3) For a column that is GENERATED BY DEFAULT, the 'value' variable in 
> UserType is a non-null instance of DefaultNodeImpl.
>
> ---------------
> -- The problem.
> ---------------
>
> In Network Server, we take the result set from the query "SELECT 
> COLUMNDEFAULT FROM SYS.SYSCOLUMNS" and we do two things.  First, we call 
> rs.getString(<columnNum>), and then we call rs.wasNull().
>
> [ ** rs.getString() ** ]
>
> * The call to rs.getString(...) on the "COLUMNDEFAULT" column ultimately 
> makes a call to UserType.getString() (Piece #2).
>
> * That method in turn calls UserType.isNull().
>
> * UserType.isNull() looks at 'value', which is a non-null instance of 
> DefaultNodeImpl(Piece #3 above), and since it's NOT null, it returns 
> "false" (Piece #2).
>
> * UserType.getString() looks at the result from UserType.isNull(), which 
> is "false".  It then calls "value.toString()" (Piece #2).
>
> * Since 'value' is an instance of DefaultNodeImpl (Piece #3), this ends up 
> being a call to DefaultNodeImpl.toString().
>
> * DefaultNodeImpl.toString() just returns 'defaultText', which is null for 
> columns that are GENERATED BY DEFAULT (Piece #1).
>
> * UserType.getString() returns the null value that it got from 
> DefaultNodeImpl.toString().
>
> * End result: the server call to "rs.getString()" returns null.
>
> [ ** rs.wasNull() ** ]
>
> * The server call to rs.wasNull() on the "COLUMNDEFAULT" column ultimately 
> makes a call to UserType.isNull().
>
> * UserType.isNull() looks at 'value', which is a non-null instance of 
> DefaultNodeImpl(Piece #3 above), and since it's NOT null, it returns 
> "false" (Piece #2).
>
> * End result: the server call to "rs.wasNull()" returns FALSE.
>
> THEREFORE, the server calls rs.getString() and gets NULL back, but then 
> when it calls rs.wasNull(), it's told that the value it got back was NOT 
> null.  So it tries to use the value (which IS null) and ends up with a 
> Null Pointer Exception.
>
> ---------------
> Possible fix:
> ---------------
>
> Just to verify that this is in the fact the problem, I changed the 
> "toString()" method in DefaultNodeImpl to the following:
>
> public String toString()
> {
> if (isDefaultValueAutoinc())
> return "GENERATED BY DEFAULT";
> return defaultText;
> }
>
> What this means is that the server call to rs.getString() will now return 
> "GENERATED BY DEFAULT" instead of null.  This in turn means that the 
> result of rs.wasNull() will be correct, and the result of the query 
> "SELECT COLUMNDEFAULT FROM SYS.SYSCOLUMNS" will be the string "GENERATED 
> BY DEFAULT".
>
> I then ran the repro described in DERBY-318, and it ran correctly, listing 
> "GENERATED BY DEFAULT" as the default value for the column in question.
>
> That said, I think returning any non-null value in 
> DefaultNodeImpl.toString() will solve the problem  The question then 
> becomes what value should we return? Is "GENERATED BY DEFAULT" an 
> acceptable result?  To me, that seems like it should be okay--it says that 
> the default value isn't known, but that it's generated at insertion time, 
> if needed.  But that's just me--it's quite possible other people out there 
> have a different opinion...
>
> ---------------
> Conclusion:
> ---------------
>
> 1) This is NOT a Network Server problem (which is what I wanted to find 
> out, and that's why I started looking at it).
>
> 2) This problem can be fixed with two lines :)  But I leave it up to the 
> others on this list to decide if this is the _best_ fix, and to decide on 
> what the non-null string value should be...
>
> I hope that helps, and I hope you don't feel cheated because I took the 
> time to look into this.  As I said, I wanted to make sure you weren't 
> chasing a problem that had its origins in Network Server...
>
> Army
>
>
>
>
> -- 
> No virus found in this incoming message.
> Checked by AVG Anti-Virus.
> Version: 7.0.322 / Virus Database: 267.2.0 - Release Date: 2005/05/27
>
> 



-- 
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.322 / Virus Database: 267.2.0 - Release Date: 2005/05/27


Re: about DERBY-318 (Re: DERBY-308 just be done and .... (Re: [jira] Updated: (DERBY-308) Modify dblook to support "GENERATED BY DEFAULT AS IDENTITY"))

Posted by TomohitoNakayama <to...@basil.ocn.ne.jp>.
Hello.

I could reproduce DERBY-318.

dblook.log@ClientSide :
-------
com.ibm.db2.jcc.c.DisconnectException: A communication error has been 
detected.
Communication protocol being used: Reply.fill(). Communication API being 
used: I
nputStream.read(). Location where the error was detected: insufficient data. 
Com
munication function detecting the error: *. Protocol specific error codes(s) 
TCP
/IP SOCKETS
        at com.ibm.db2.jcc.a.a.a(a.java:426)
        at com.ibm.db2.jcc.a.bb.b(bb.java:202)
com.ibm.db2.jcc.c.DisconnectException: A communication error has been 
detected.
Communication protocol being used: Reply.fill(). Communication API being 
used: I
nputStream.read(). Location where the error was detected: insufficient data. 
Com
munication function detecting the error: *. Protocol specific error codes(s) 
TCP
/IP SOCKETS
        at com.ibm.db2.jcc.a.a.a(a.java:426)
        at com.ibm.db2.jcc.a.bb.b(bb.java:202)
        at com.ibm.db2.jcc.a.bb.c(bb.java:222)
        at com.ibm.db2.jcc.a.bb.d(bb.java:236)
        at com.ibm.db2.jcc.a.eb.a(eb.java:1911)
        at com.ibm.db2.jcc.a.fb.a(fb.java:134)
        at com.ibm.db2.jcc.a.fb.a(fb.java:34)
        at com.ibm.db2.jcc.a.s.a(s.java:30)
        at com.ibm.db2.jcc.a.h.Gb(h.java:325)
        at com.ibm.db2.jcc.c.rc.R(rc.java:3028)
        at com.ibm.db2.jcc.a.d.f(d.java:1070)
        at com.ibm.db2.jcc.c.r.a(r.java:191)
        at com.ibm.db2.jcc.c.rc.c(rc.java:302)
        at com.ibm.db2.jcc.c.rc.next(rc.java:277)
        at 
org.apache.derby.impl.tools.dblook.DB_Table.createColumn(DB_Table.jav
a:143)
        at 
org.apache.derby.impl.tools.dblook.DB_Table.doTables(DB_Table.java:10
1)
        at org.apache.derby.tools.dblook.go(dblook.java:529)


STDERR@ServerSide:
-----------------
null
java.lang.NullPointerException
        at 
org.apache.derby.impl.drda.DRDAConnThread.writeFdocaVal(DRDAConnThread.java:6550)
        at 
org.apache.derby.impl.drda.DRDAConnThread.writeFDODTA(DRDAConnThread.java:5973)
        at 
org.apache.derby.impl.drda.DRDAConnThread.writeQRYDTA(DRDAConnThread.java:5796)
        at 
org.apache.derby.impl.drda.DRDAConnThread.processCommands(DRDAConnThread.java:595)
        at 
org.apache.derby.impl.drda.DRDAConnThread.run(DRDAConnThread.java:226)
agentThread[DRDAConnThread_2,5,main]
null
java.lang.NullPointerException
        at 
org.apache.derby.impl.drda.DRDAConnThread.writeFdocaVal(DRDAConnThread.java:6550)
        at 
org.apache.derby.impl.drda.DRDAConnThread.writeFDODTA(DRDAConnThread.java:5973)
        at 
org.apache.derby.impl.drda.DRDAConnThread.writeQRYDTA(DRDAConnThread.java:5796)
        at 
org.apache.derby.impl.drda.DRDAConnThread.processCommands(DRDAConnThread.java:595)
        at 
org.apache.derby.impl.drda.DRDAConnThread.run(DRDAConnThread.java:226)

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

I will start to consider how to fix the contradiction ....


Best regards.

/*

         Tomohito Nakayama
         tomonaka@basil.ocn.ne.jp
         tomohito@rose.zero.ad.jp

         Naka
         http://www5.ocn.ne.jp/~tomohito/TopPage.html

*/
----- Original Message ----- 
From: "TomohitoNakayama" <to...@basil.ocn.ne.jp>
To: "Derby Development" <de...@db.apache.org>
Sent: Saturday, May 28, 2005 1:51 PM
Subject: about DERBY-318 (Re: DERBY-308 just be done and .... (Re: [jira] 
Updated: (DERBY-308) Modify dblook to support "GENERATED BY DEFAULT AS 
IDENTITY"))


> Hello.
>
> First of all, thank you for your kindness !
>
> I understood the problem is that
> there exists contradiction between rs.getString() and rs.wasNull()
> for SYSCOLUMNS.COLUMNDEFAULT of column defined as GENERATED BY DEFAULT AS 
> IDENTITY.
>
> I will start to see pheonemanas in my environment.
>
>
> I think we need to consider way to solve DERBY-318 .
>
> page 321 at next document says..
> http://publibfp.boulder.ibm.com/epubs/pdf/cs51rm.pdf
>
> for tables, describes default value of the column.
> The toString() method on the object stored in the table returns the text 
> of the default value as specified in the
> CREATE TABLE or ALTER TABLE statement.
>
> for publication parameters, defines the default value of the parameter at 
> the source,
> and the actual value of the parameter at the target
> for stored prepared statements, defines a sample value for the parameter 
> used in a
> CREATE STATEMENTor ALTER STATEMENT RECOMPILE statement
> for optimization purposes
>
> This is issue about table , so it is the matter how to interpret "text of 
> the default value as specified in the
> CREATE TABLE or ALTER TABLE statement"
>
> //BTW, what is publication parameters ...?
> // I took somethink like table ....
>
>
> Best regards.
>
> /*
>
>         Tomohito Nakayama
>         tomonaka@basil.ocn.ne.jp
>         tomohito@rose.zero.ad.jp
>
>         Naka
>         http://www5.ocn.ne.jp/~tomohito/TopPage.html
>
> */
> ----- Original Message ----- 
> From: "Army" <qo...@sbcglobal.net>
> To: "Derby Development" <de...@db.apache.org>
> Sent: Saturday, May 28, 2005 10:03 AM
> Subject: Re: DERBY-308 just be done and .... (Re: [jira] Updated: 
> (DERBY-308) Modify dblook to support "GENERATED BY DEFAULT AS IDENTITY")
>
>
>> TomohitoNakayama wrote:
>>
>>> If possible , I want to work for DERBY-318 before DERBY-308 ....
>>
>> Tomohito,
>>
>> I hope you don't mind, but when I filed DERBY-318, I wasn't sure whether 
>> the problem was with the DERBY-167 patch or with the server.  So, in 
>> order to keep you from spending your time trying to track down a problem 
>> that wasn't your fault, I started looking at this issue from the server 
>> side of things--and I think I've found the problem.
>>
>> To make a long story short, the NPE in the server happens because of the 
>> "toString()" method defined in DefaultNodeImpl.
>>
>> Why?  Well, I try to explain it below.  Excuse the formality of it all, 
>> but I had to do it this way in order to keep it clear in my own head ;)
>>
>> There are several pieces that make up the puzzle.  Let me start by saying 
>> what they are, and then I'll try to tie them together.
>>
>> ---------------
>> -- The pieces.
>> ---------------
>>
>> 1) For a column that is GENERATED BY DEFAULT, the 'defaultText' variable 
>> in the corresponding DefaultNodeImpl is null.  Since 
>> DefaultNodeImpl.toString() just returns defaultText, the result of 
>> toString() on a DefaultNodeImpl that is GENERATED BY DEFAULT is null.
>>
>> 2) The underlying DataTypeDescriptor for all default columns is 
>> "org.apache.derby.iapi.types.UserType".  In that class, the "isNull()" 
>> method is simply written to return "(value == null)", while the 
>> "getString()" method is as follows:
>>
>> public String getString()
>> {
>> if (! isNull())
>> {
>> return value.toString();
>> }
>> else
>> {
>> return null;
>> }
>> }
>>
>> 3) For a column that is GENERATED BY DEFAULT, the 'value' variable in 
>> UserType is a non-null instance of DefaultNodeImpl.
>>
>> ---------------
>> -- The problem.
>> ---------------
>>
>> In Network Server, we take the result set from the query "SELECT 
>> COLUMNDEFAULT FROM SYS.SYSCOLUMNS" and we do two things.  First, we call 
>> rs.getString(<columnNum>), and then we call rs.wasNull().
>>
>> [ ** rs.getString() ** ]
>>
>> * The call to rs.getString(...) on the "COLUMNDEFAULT" column ultimately 
>> makes a call to UserType.getString() (Piece #2).
>>
>> * That method in turn calls UserType.isNull().
>>
>> * UserType.isNull() looks at 'value', which is a non-null instance of 
>> DefaultNodeImpl(Piece #3 above), and since it's NOT null, it returns 
>> "false" (Piece #2).
>>
>> * UserType.getString() looks at the result from UserType.isNull(), which 
>> is "false".  It then calls "value.toString()" (Piece #2).
>>
>> * Since 'value' is an instance of DefaultNodeImpl (Piece #3), this ends 
>> up being a call to DefaultNodeImpl.toString().
>>
>> * DefaultNodeImpl.toString() just returns 'defaultText', which is null 
>> for columns that are GENERATED BY DEFAULT (Piece #1).
>>
>> * UserType.getString() returns the null value that it got from 
>> DefaultNodeImpl.toString().
>>
>> * End result: the server call to "rs.getString()" returns null.
>>
>> [ ** rs.wasNull() ** ]
>>
>> * The server call to rs.wasNull() on the "COLUMNDEFAULT" column 
>> ultimately makes a call to UserType.isNull().
>>
>> * UserType.isNull() looks at 'value', which is a non-null instance of 
>> DefaultNodeImpl(Piece #3 above), and since it's NOT null, it returns 
>> "false" (Piece #2).
>>
>> * End result: the server call to "rs.wasNull()" returns FALSE.
>>
>> THEREFORE, the server calls rs.getString() and gets NULL back, but then 
>> when it calls rs.wasNull(), it's told that the value it got back was NOT 
>> null.  So it tries to use the value (which IS null) and ends up with a 
>> Null Pointer Exception.
>>
>> ---------------
>> Possible fix:
>> ---------------
>>
>> Just to verify that this is in the fact the problem, I changed the 
>> "toString()" method in DefaultNodeImpl to the following:
>>
>> public String toString()
>> {
>> if (isDefaultValueAutoinc())
>> return "GENERATED BY DEFAULT";
>> return defaultText;
>> }
>>
>> What this means is that the server call to rs.getString() will now return 
>> "GENERATED BY DEFAULT" instead of null.  This in turn means that the 
>> result of rs.wasNull() will be correct, and the result of the query 
>> "SELECT COLUMNDEFAULT FROM SYS.SYSCOLUMNS" will be the string "GENERATED 
>> BY DEFAULT".
>>
>> I then ran the repro described in DERBY-318, and it ran correctly, 
>> listing "GENERATED BY DEFAULT" as the default value for the column in 
>> question.
>>
>> That said, I think returning any non-null value in 
>> DefaultNodeImpl.toString() will solve the problem  The question then 
>> becomes what value should we return? Is "GENERATED BY DEFAULT" an 
>> acceptable result?  To me, that seems like it should be okay--it says 
>> that the default value isn't known, but that it's generated at insertion 
>> time, if needed.  But that's just me--it's quite possible other people 
>> out there have a different opinion...
>>
>> ---------------
>> Conclusion:
>> ---------------
>>
>> 1) This is NOT a Network Server problem (which is what I wanted to find 
>> out, and that's why I started looking at it).
>>
>> 2) This problem can be fixed with two lines :)  But I leave it up to the 
>> others on this list to decide if this is the _best_ fix, and to decide on 
>> what the non-null string value should be...
>>
>> I hope that helps, and I hope you don't feel cheated because I took the 
>> time to look into this.  As I said, I wanted to make sure you weren't 
>> chasing a problem that had its origins in Network Server...
>>
>> Army
>>
>>
>>
>>
>> -- 
>> No virus found in this incoming message.
>> Checked by AVG Anti-Virus.
>> Version: 7.0.322 / Virus Database: 267.2.0 - Release Date: 2005/05/27
>>
>>
>
>
>
> -- 
> No virus found in this outgoing message.
> Checked by AVG Anti-Virus.
> Version: 7.0.322 / Virus Database: 267.2.0 - Release Date: 2005/05/27
>
>
>
>
> -- 
> No virus found in this incoming message.
> Checked by AVG Anti-Virus.
> Version: 7.0.322 / Virus Database: 267.2.0 - Release Date: 2005/05/27
>
> 



-- 
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.322 / Virus Database: 267.2.0 - Release Date: 2005/05/27