Uploaded image for project: 'Teiid'
  1. Teiid
  2. TEIID-6048

NPE on query planning

    XMLWordPrintable

Details

    • Hide

      1. In PostgreSQL create the test_a and test_b tables using the following scripts:

      CREATE TABLE public.table_a
      (
        shop_key character varying(4000),
        channel_key character varying(4000)
      );
      INSERT INTO public.table_a(
                  shop_key, channel_key)
          VALUES ('shop_key', 'channel_key');
      
      CREATE TABLE public.table_b
      (
        shop_key character varying(4000),
        dummy character varying(4000),
        medium character varying(4000)
      );
      INSERT INTO public.table_b(
                  shop_key, dummy, medium)
          VALUES ('shop_key', 'dummy', 'channel');
      

      2. Add PostgreSQL database configuration in standalone-teiid.xml:

                      <datasource jndi-name="java:/test_dwh_pg" pool-name="test_dwh_pg" enabled="true" use-java-context="true">
                          <connection-url>jdbc:postgresql://localhost:5432/test_dwh?charSet=utf8</connection-url>
                          <driver-class>org.postgresql.Driver</driver-class>
                          <driver>org.postgresql</driver>
                          <pool>
                              <min-pool-size>2</min-pool-size>
                              <max-pool-size>70</max-pool-size>
                              <prefill>false</prefill>
                              <use-strict-min>false</use-strict-min>
                              <flush-strategy>FailingConnectionOnly</flush-strategy>
                          </pool>
                          <security>
                              <user-name>xxxxx</user-name>
                              <password>xxxxx</password>
                          </security>
                          <validation>
                              <check-valid-connection-sql>select 0</check-valid-connection-sql>
                          </validation>
                          <timeout>
                              <blocking-timeout-millis>120000</blocking-timeout-millis>
                              <idle-timeout-minutes>5</idle-timeout-minutes>
                          </timeout>
                      </datasource>
      

      3. Add in test-vdb.xml java:/test_dwh_pg configured in the previous step as a data source:

          <model name="test_dwh_pg">
              <property name="importer.useFullSchemaName" value="false"/>
              <property name="importer.tableTypes" value="TABLE,VIEW"/>
              <property name="importer.importKeys" value="false"/>
              <source name="test_dwh_pg" translator-name="myPg" connection-jndi-name="java:/test_dwh_pg"/>
          </model>
          <translator name="myPg" type="postgresql">
              <property name="SupportsNativeQueries" value="true"/>
          </translator>
      

      4. Add in test-vdb.xml the views.p1 virtual procedure:

      <model visible = "true" type = "VIRTUAL" name = "views">
              <metadata type = "DDL"><![CDATA[
                create virtual procedure p1(in dummy string) returns (procedure_result string)
      as begin
      	select 'key' procedure_result;
      end
              ]]>
              </metadata>
          </model>
      

      5. Call either SYSADMIN.setTableStats or SYSADMIN.setColumnStats stored procedures:

      call "SYSADMIN.setTableStats"(
          "cardinality" => 1,
          "tableName" => 'test_dwh_pg.table_a'
      ) ;;
      

      or a couple of these procedures:

      call "SYSADMIN.setColumnStats"(
          "columnName" => 'channel_key',
          "distinctCount" => 1,
          "max" => '-1',
          "min" => '-1',
          "nullCount" => 0,
          "tableName" => 'test_dwh_pg.table_a'
      ) ;;
       
      call "SYSADMIN.setColumnStats"(
          "columnName" => 'shop_key',
          "distinctCount" => 1,
          "max" => '-1',
          "min" => '-1',
          "nullCount" => 0,
          "tableName" => 'test_dwh_pg.table_a'
      ) ;;
      

      6. Run the following query:

      select "a.shop_key" -- it doesn't matter what is selected here
      from 
      	(
      		select "shop_key", "channel_key" 
      		from "test_dwh_pg.table_a"
      	) a
      	join 
      		(
      			select
      				table_b."shop_key",  
      				table_b.medium || '_' || p.procedure_result as "channel_key" -- mandatory: coalesce between one field from dwhtable and a result field from proc (with proc consuming adwh table field)
      			from test_dwh_pg."table_b" 
      			, table( exec views.p1(dummy)) p -- any field from dwh table may be consumed, one field has to be consumed
      		) b 
      		on 
      			"b.shop_key" = "a.shop_key" 
      			and "b.channel_key" = "a.channel_key" -- mandatory: 2 fields in on clause
      ;;
      
      Show
      1. In PostgreSQL create the test_a and test_b tables using the following scripts: CREATE TABLE public .table_a ( shop_key character varying (4000), channel_key character varying (4000) ); INSERT INTO public .table_a( shop_key, channel_key) VALUES ( 'shop_key' , 'channel_key' ); CREATE TABLE public .table_b ( shop_key character varying (4000), dummy character varying (4000), medium character varying (4000) ); INSERT INTO public .table_b( shop_key, dummy , medium) VALUES ( 'shop_key' , ' dummy ' , 'channel' ); 2. Add PostgreSQL database configuration in standalone-teiid.xml: <datasource jndi-name= "java:/test_dwh_pg" pool-name= "test_dwh_pg" enabled= "true" use-java-context= "true" > <connection-url> jdbc:postgresql://localhost:5432/test_dwh?charSet=utf8 </connection-url> <driver-class> org.postgresql.Driver </driver-class> <driver> org.postgresql </driver> <pool> <min-pool-size> 2 </min-pool-size> <max-pool-size> 70 </max-pool-size> <prefill> false </prefill> <use-strict-min> false </use-strict-min> <flush-strategy> FailingConnectionOnly </flush-strategy> </pool> <security> <user-name> xxxxx </user-name> <password> xxxxx </password> </security> <validation> <check-valid-connection-sql> select 0 </check-valid-connection-sql> </validation> <timeout> <blocking-timeout-millis> 120000 </blocking-timeout-millis> <idle-timeout-minutes> 5 </idle-timeout-minutes> </timeout> </datasource> 3. Add in test-vdb.xml java:/test_dwh_pg configured in the previous step as a data source: <model name= "test_dwh_pg" > <property name= "importer.useFullSchemaName" value= "false" /> <property name= "importer.tableTypes" value= "TABLE,VIEW" /> <property name= "importer.importKeys" value= "false" /> <source name= "test_dwh_pg" translator-name= "myPg" connection-jndi-name= "java:/test_dwh_pg" /> </model> <translator name= "myPg" type= "postgresql" > <property name= "SupportsNativeQueries" value= "true" /> </translator> 4. Add in test-vdb.xml the views.p1 virtual procedure: <model visible = "true" type = "VIRTUAL" name = "views" > <metadata type = "DDL" > <![CDATA[ create virtual procedure p1(in dummy string) returns (procedure_result string) as begin select 'key' procedure_result; end ]]> </metadata> </model> 5. Call either SYSADMIN.setTableStats or SYSADMIN.setColumnStats stored procedures: call "SYSADMIN.setTableStats" ( " cardinality " => 1, "tableName" => 'test_dwh_pg.table_a' ) ;; or a couple of these procedures: call "SYSADMIN.setColumnStats" ( "columnName" => 'channel_key' , "distinctCount" => 1, " max " => '-1' , " min " => '-1' , "nullCount" => 0, "tableName" => 'test_dwh_pg.table_a' ) ;; call "SYSADMIN.setColumnStats" ( "columnName" => 'shop_key' , "distinctCount" => 1, " max " => '-1' , " min " => '-1' , "nullCount" => 0, "tableName" => 'test_dwh_pg.table_a' ) ;; 6. Run the following query: select " a .shop_key" -- it doesn't matter what is selected here from ( select "shop_key" , "channel_key" from "test_dwh_pg.table_a" ) a join ( select table_b. "shop_key" , table_b.medium || '_' || p.procedure_result as "channel_key" -- mandatory: coalesce between one field from dwhtable and a result field from proc ( with proc consuming adwh table field) from test_dwh_pg. "table_b" , table ( exec views.p1( dummy )) p -- any field from dwh table may be consumed, one field has to be consumed ) b on "b.shop_key" = " a .shop_key" and "b.channel_key" = " a .channel_key" -- mandatory: 2 fields in on clause ;;

    Description

      Teiid throws the following NPE:

      2020-11-06 15:57:17,903 ERROR [org.teiid.PROCESSOR] (Worker2_QueryProcessorQueue20) AroM4jm+JTFz TEIID30019 Unexpected exception for request AroM4jm+JTFz.4: java.lang.NullPointerException                                                                                                                                                                                         at org.teiid.query.sql.navigator.PreOrderNavigator.doVisit(PreOrderNavigator.java:36)                                                                                                 at org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(ValueIteratorProviderCollectorVisitor.java:149)                                        at org.teiid.query.optimizer.relational.plantree.PlanNode.getSubqueryContainers(PlanNode.java:428)                                                                                    at org.teiid.query.optimizer.relational.plantree.PlanNode.getCorrelatedReferences(PlanNode.java:327)                                                                                  at org.teiid.query.optimizer.relational.plantree.PlanNode.getCorrelatedReferenceElements(PlanNode.java:373)                                                                           at org.teiid.query.optimizer.relational.RelationalPlanner.createSelectNode(RelationalPlanner.java:1906)                                                                               at org.teiid.query.optimizer.relational.rules.RuleChooseDependent.createDependentSetNode(RuleChooseDependent.java:675)                                                                at org.teiid.query.optimizer.relational.rules.RulePushSelectCriteria.moveCriteriaIntoOnClause(RulePushSelectCriteria.java:327)                                                        at org.teiid.query.optimizer.relational.rules.RulePushSelectCriteria.handleJoinCriteria(RulePushSelectCriteria.java:268)                                                              at org.teiid.query.optimizer.relational.rules.RulePushSelectCriteria.execute(RulePushSelectCriteria.java:137)                                                                         at org.teiid.query.optimizer.relational.RelationalPlanner.executeRules(RelationalPlanner.java:1101)                                                                                   at org.teiid.query.optimizer.relational.RelationalPlanner.optimize(RelationalPlanner.java:235)                                                                                        at org.teiid.query.optimizer.QueryOptimizer.optimizePlan(QueryOptimizer.java:181)                                                                                                     at org.teiid.dqp.internal.process.Request.generatePlan(Request.java:483)                                                                                                              at org.teiid.dqp.internal.process.Request.processRequest(Request.java:511)                                                                                                            at org.teiid.dqp.internal.process.RequestWorkItem.processNew(RequestWorkItem.java:671)                                                                                                at org.teiid.dqp.internal.process.RequestWorkItem.process(RequestWorkItem.java:350)                                                                                                   at org.teiid.dqp.internal.process.AbstractWorkItem.run(AbstractWorkItem.java:43)                                                                                                      at org.teiid.dqp.internal.process.RequestWorkItem.run(RequestWorkItem.java:284)                                                                                                       at org.teiid.dqp.internal.process.DQPWorkContext.runInContext(DQPWorkContext.java:281)                                                                                                at org.teiid.dqp.internal.process.ThreadReuseExecutor$RunnableWrapper.run(ThreadReuseExecutor.java:124)                                                                               at org.teiid.dqp.internal.process.ThreadReuseExecutor$2.run(ThreadReuseExecutor.java:212)                                                                                             at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)                                                                                                    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)                                                                                                    at java.lang.Thread.run(Thread.java:745)
      

      on the planning of a particular kind of query (see workflow to reproduce).

      Attachments

        Activity

          People

            rhn-engineering-shawkins Steven Hawkins
            dalex005 Dmitrii Pogorelov
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: