Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Problem with Postgres 9.x and getNextSequenceValue on 3.1p

    Hi,

    I have a problem that occurs with doing an insert with a serial/sequence value on Postgres 9.0.13 and this problem only occurs when I upgrade my application from SmartGWT Power 3.0p to 3.1p (4/16 nightly).

    The string that is created as the parameter to the nextval() built-in function has the last letter of the table name truncated and then when the sequence name is appended to it, the result string is invalid and therefore PGSQL complains that "The relation does not exist". The data source that this occurs on is created with "autoDeriveSchema" set to true, so I do not explicitly name the sequence in the ds.xml file.

    For example, in my log fragment below you can see that my schema, table name, and sequenced column name are all correctly formatted at the beginning of the INSERT statement ("beari_application_beari_test_2013_01_15","schema_state_history", and "history_id" respectively), but when those values are appended together to form the value passed to nextval(), things get mangled into:
    Code:
     
    INSERT INTO beari_application_beari_test_2013_01_15.schema_state_history (comments, state_code, updated_by, history_id) 
    VALUES ('', 2, 'beari_tester', nextval('beari_application_beari_test_2013_01_15.schema_state_histor_history_id'))
    Log:
    Code:
    === 2013-04-16 19:32:53,205 [c-25] INFO  IDACall - Performing 1 operation(s)
    === 2013-04-16 19:32:53,205 [c-25] INFO  SQLDataSource - [builtinApplication.bemanager_beari_application_beari_test_2013_01_15:schema_state_history_add] Performing add operation with
    	criteria: {state_code:2,comments:"",updated_by:"beari_tester"}	values: {state_code:2,comments:"",updated_by:"beari_tester"}
    === 2013-04-16 19:32:53,220 [c-25] INFO  SQLDriver - [builtinApplication.bemanager_beari_application_beari_test_2013_01_15:schema_state_history_add] Executing SQL update on 'v3_sandbox': INSERT INTO beari_application_beari_test_2013_01_15.schema_state_history (comments, state_code, updated_by, history_id) VALUES ('', 2, 'beari_tester', nextval('beari_application_beari_test_2013_01_15.schema_state_histor_history_id'))
    === 2013-04-16 19:32:53,267 [c-25] WARN  RequestContext - dsRequest.execute() failed: 
    org.postgresql.util.PSQLException: ERROR: relation "beari_application_beari_test_2013_01_15.schema_state_histor_history_id" does not exist
      Position: 165
    	at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
    	at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
    	at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    	at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
    	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
    	at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334)
    	at com.isomorphic.sql.SQLDriver.doUpdate(SQLDriver.java:750)
    	at com.isomorphic.sql.SQLDriver.update(SQLDriver.java:700)
    	at com.isomorphic.sql.SQLDriver.executeUpdate(SQLDriver.java:824)
    	at com.isomorphic.sql.SQLDataSource.executeNativeUpdate(SQLDataSource.java:419)
    	at com.isomorphic.sql.SQLDataSource.SQLExecute(SQLDataSource.java:1464)
    	at com.isomorphic.sql.SQLDataSource.processRequest(SQLDataSource.java:306)
    	at com.isomorphic.sql.SQLDataSource.executeAdd(SQLDataSource.java:258)
    	at com.isomorphic.datasource.DataSource.execute(DataSource.java:1370)
    	at com.isomorphic.application.AppBase.executeDefaultDSOperation(AppBase.java:726)
    	at com.isomorphic.application.AppBase.executeAppOperation(AppBase.java:658)
    	at com.isomorphic.application.AppBase.execute(AppBase.java:491)
    	at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:2031)
    	at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:216)
    	at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:173)
    	at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:138)
    	at com.isomorphic.servlet.IDACall.doPost(IDACall.java:74)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    	at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    	at com.isomorphic.servlet.CompressionFilter.doFilter(CompressionFilter.java:259)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    	at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
    	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
    	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
    	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    	at java.lang.Thread.run(Thread.java:662)

    On 3.0p, the INSERT statement does *not* create the nextval() invocation as part of the INSERT statement but Postgres does the right thing because it knows what sequence to call implicitly when a new record is added and the sequenced column name is not specified.

    Code:
    INSERT INTO beari_application_beari_test_2013_01_15.schema_state_history (comments, state_code, updated_by) 
    VALUES ('', 1, 'beari_tester')
    Log:
    Code:
    === 2013-04-16 20:21:55,679 [c-18] INFO  IDACall - Performing 1 operation(s)
    === 2013-04-16 20:21:55,679 [c-18] INFO  SQLDataSource - [builtinApplication.bemanager_beari_application_beari_test_2013_01_15:schema_state_history_add] Performing add operation with
    	criteria: {state_code:1,comments:"",updated_by:"beari_tester"}	values: {state_code:1,comments:"",updated_by:"beari_mail_tester"}
    === 2013-04-16 20:21:55,710 [c-18] INFO  SQLDriver - [builtinApplication.bemanager_beari_application_beari_test_2013_01_15:schema_state_history_add] Executing SQL update on 'v3_sandbox': INSERT INTO beari_application_beari_test_2013_01_15.schema_state_history (comments, state_code, updated_by) VALUES ('', 1, 'beari_tester')
    I am curious about the difference in the way this is handled between 3.0p and 3.1p and the logic used to determine the sequence name. For example, the real name of the sequence in my Postgres DB is actually:
    Code:
    beari_application_beari_test_2013_01_15.schema_state_history_history_id_seq
    So if SmartGWT generated what I assume would be the result without the truncation:
    Code:
    beari_application_beari_test_2013_01_15.schema_state_history_history_id
    Then the value for nextval() would still be incorrect. Any thoughts on this?

    If needed I can create a separate test case for this and repost, however I was hoping that in the case that this might be something simple and/or obvious that you would consider looking into with the information I have provided in this post.

    Thanks for your consideration,
    Mike
    Last edited by mdarcy; 17 Apr 2013, 12:09.

    #2
    Hate to bump myself, but any comment on this? I would really like to upgrade our application from 3.0 to 3.1, but this issue is preventing that.

    Mike

    Comment


      #3
      Please show your datasource

      Comment


        #4
        Thanks for responding. The datasource is using "autoDeriveSchema". I am pasting below the datasource, table schema as output by Postgres, and associated sequence name as created implicitly by Postgres when the table is created.

        Data Source:
        Code:
        <DataSource 
        	schema="beari_application_beari_test_2013_01_15"
        	dbName="v3_sandbox"
        	tableName="schema_state_history"
        	ID="schema_state_history"
        	serverType="sql"
            autoDeriveSchema="true"
        />
        Table creation schema:
        Code:
        -- DROP TABLE beari_application_beari_test_2013_01_15.schema_state_history;
        
        CREATE TABLE beari_application_beari_test_2013_01_15.schema_state_history
        (
          history_id serial NOT NULL,
          state_code integer NOT NULL,
          update_time timestamp without time zone NOT NULL DEFAULT now(),
          updated_by text,
          comments text,
          CONSTRAINT schema_state_history_pkey PRIMARY KEY (history_id ),
          CONSTRAINT schema_state_history_state_code_fkey FOREIGN KEY (state_code)
              REFERENCES beari_applications.schema_state_codes (state_code) MATCH SIMPLE
              ON UPDATE NO ACTION ON DELETE NO ACTION
        )
        WITH (
          OIDS=FALSE
        );
        ALTER TABLE beari_application_beari_test_2013_01_15.schema_state_history
          OWNER TO beariuser;
        GRANT ALL ON TABLE beari_application_beari_test_2013_01_15.schema_state_history TO beariuser;
        GRANT SELECT ON TABLE beari_application_beari_test_2013_01_15.schema_state_history TO beari_application_reader;
        GRANT INSERT ON TABLE beari_application_beari_test_2013_01_15.schema_state_history TO beari_history_updater;
        GRANT SELECT, UPDATE, INSERT ON TABLE beari_application_beari_test_2013_01_15.schema_state_history TO beari_test;
        Sequence creation schema:
        Code:
        CREATE SEQUENCE beari_application_beari_test_2013_01_15.schema_state_history_history_id_seq
          INCREMENT 0
          MINVALUE 0
          MAXVALUE 0
          START 0
          CACHE 0;
        ALTER TABLE beari_application_beari_test_2013_01_15.schema_state_history_history_id_seq
          OWNER TO beariuser;
        GRANT ALL ON TABLE beari_application_beari_test_2013_01_15.schema_state_history_history_id_seq TO beariuser;
        GRANT UPDATE ON TABLE beari_application_beari_test_2013_01_15.schema_state_history_history_id_seq TO beari_history_updater;
        Please let me know if you would like any more information.

        Thanks,
        Mike

        Comment


          #5
          Ok, we'll take a look and update this thread when we have more information.

          In the meantime, you can try adding a <fields> block to your DS and specifying just the sequence field, marking it as type sequence and providing the sequenceName along with it
          Last edited by Isomorphic; 20 Apr 2013, 21:26.

          Comment


            #6
            We have made some changes to sequence handling to properly cope with both "traditional" sequence use in Postgres (where you create a sequence object and manually call nextval() on it), and the kind of semi-automatic sequence usage that happens when you use the "serial" column type, which we guess is what you are using here?

            The change will be present in today's 4.0d and 3.1p builds (dated 4/23 or later).

            Comment


              #7
              Thank you very much for looking into this. I downloaded today's 4/23 build of 3.1p Power, but unfortunately I do not see any difference after updating my app to use the new code. The generated insert statement is identical to the previous version (i.e., still using nextval()).

              If I read your last post correctly, the intended behavior is that nextval() will not be inserted into the statement when the field type is "serial", but it doesn't seem like it is triggering in my case.

              Unfortunately, I cannot use the workaround of adding just the sequence name to a <fields> block because I use a custom data source generator to generate these DS descriptors at runtime by querying a view in our database to discover what tables to load.

              So, since I don't know what all the data sources are ahead of time, and I don't know which of those data sources have sequence-based fields in them, it is important that "autoDeriveSchema" figures out the proper course of action for dealing with serial fields.

              This is basically all my custom DS generator does:
              Code:
                      try 
                      {
                          String xmlString =
              		"<DataSource\r" +
              		"    ID=\"" + id + "\"\r" +
                              "    schema=\"" + schemaName + "\"\r" + 
                              "    tableName=\"" + tableName + "\"\r" +
                              "    serverType=\"sql\"\r" +
                              "    autoDeriveSchema=\"true\"\r" +
                              "    progressiveLoading=\"true\"\r" +                  
              		"/>\r";
                          
                          return DataSource.fromXML(xmlString);
                      } catch (Exception e) {
                          log.error(e);
                          return null;
                      }
              Note that this custom DS generator works fine and I don't suspect it has anything to do with this issue, but I wanted to include the code fragment for posterity.

              I will try to update again with tomorrow's build in case somehow the change didn't make it into today's. I can also create a standalone test case for this if you think it will help.

              Thanks again and best regards,
              Mike

              Comment


                #8
                The changes didn't make it into yesterday's nightly because of a change in our build system whereby we build from a snapshot of version control at a known point in time, rather than just the current state of the branch.

                Sorry about that - please try today's build.

                Comment


                  #9
                  Hi,

                  Just tried the new version and works fine! Thanks for resolving this.

                  I noticed that immediately after the INSERT it now does a SELECT for the currval() of the sequence, followed by another SELECT for the record that matches the result of the currval(). This is not a problem for me, but I do not recall it doing that in 3.0p and was curious about the change in behavior.

                  My application does not need to know this value or select this record after the insert -- I am just presenting all of the table data in a databound ListGrid. Is this behavior something that the ListGrid is causing, or is it in the SQLDataSource code (or some related part). Just curious...

                  Code:
                  === 2013-04-24 14:44:58,694 [c-30] INFO  IDACall - Performing 1 operation(s)
                  === 2013-04-24 14:44:58,695 [c-30] INFO  SQLDataSource - [builtinApplication.beviewer_beari_application_beari_test_2013_01_15:schema_state_history_add] Performing add operation with
                  	criteria: {state_code:1,comments:null,updated_by:"mdarcy"}	values: {state_code:1,comments:null,updated_by:"mdarcy"}
                  === 2013-04-24 14:44:58,827 [c-30] INFO  SQLDriver - [builtinApplication.beviewer_beari_application_beari_test_2013_01_15:schema_state_history_add] Executing SQL update on 'v3_sandbox': INSERT INTO beari_application_beari_test_2013_01_15.schema_state_history (comments, state_code, updated_by) VALUES (NULL, 1, 'mdarcy')
                  === 2013-04-24 14:44:58,833 [c-30] INFO  SQLDriver - [builtinApplication.beviewer_beari_application_beari_test_2013_01_15:schema_state_history_add] Executing SQL query on 'v3_sandbox': SELECT currval('beari_application_beari_test_2013_01_15.schema_state_history_history_id_seq')
                  === 2013-04-24 14:44:58,867 [c-30] INFO  SQLDataSource - [builtinApplication.beviewer_beari_application_beari_test_2013_01_15:schema_state_history_add] primaryKeys: {history_id=108}
                  === 2013-04-24 14:44:58,868 [c-30] INFO  SQLDataSource - [builtinApplication.beviewer_beari_application_beari_test_2013_01_15:schema_state_history_add, builtinApplication.null] Performing fetch operation with
                  	criteria: {history_id:108}	values: {history_id:108}
                  === 2013-04-24 14:44:58,868 [c-30] INFO  SQLDataSource - [builtinApplication.beviewer_beari_application_beari_test_2013_01_15:schema_state_history_add, builtinApplication.null] derived query: SELECT $defaultSelectClause FROM $defaultTableClause WHERE $defaultWhereClause
                  === 2013-04-24 14:44:58,916 [c-30] INFO  SQLDataSource - [builtinApplication.beviewer_beari_application_beari_test_2013_01_15:schema_state_history_add, builtinApplication.null] Executing SQL query on 'v3_sandbox': SELECT schema_state_history.comments, schema_state_history.history_id, schema_state_history.state_code, schema_state_history.update_time, schema_state_history.updated_by FROM beari_application_beari_test_2013_01_15.schema_state_history WHERE (schema_state_history.history_id=108)
                  === 2013-04-24 14:44:58,916 [c-30] INFO  SQLDriver - [builtinApplication.beviewer_beari_application_beari_test_2013_01_15:schema_state_history_add, builtinApplication.null] Executing SQL query on 'v3_sandbox': SELECT schema_state_history.comments, schema_state_history.history_id, schema_state_history.state_code, schema_state_history.update_time, schema_state_history.updated_by FROM beari_application_beari_test_2013_01_15.schema_state_history WHERE (schema_state_history.history_id=108)
                  === 2013-04-24 14:44:58,967 [c-30] INFO  DSResponse - [builtinApplication.beviewer_beari_application_beari_test_2013_01_15:schema_state_history_add, builtinApplication.null] DSResponse: List with 1 items
                  Anyway it is not a big deal for me at this time, and I am very glad that we can now upgrade our app to 3.1p! Thanks again for knocking this out so quick.

                  Cheers,
                  Mike
                  Last edited by mdarcy; 24 Apr 2013, 14:14.

                  Comment


                    #10
                    That's a SQLDataSource behavior. We are selecting the record-as-saved from the DB so that it can be returned back to the browser to update caches. The UI will need the generated primary key in order to do subsequent updates against the same record, will also need to get values for any other server-generated columns that are displayed in the UI (eg columns that store the time of the last update).

                    Comment


                      #11
                      Understood. Thank you for clarifying.

                      Comment

                      Working...
                      X