Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-23825

Join select_handler and Pushdown_select + XPand changes

Details

    Description

      Under terms of this task we'll do two things:

      • Join classes select_handler and Pushdown_select into a single class
        The current implementation with two parallel classes (select_handler and Pushdown_select) is hard to follow. Non of them can work without the other. The two-step construction stage looks too complex:

          select_lex->select_h= select_lex->find_select_handler(thd);
          if (select_lex->select_h)
          {
            /* Create a Pushdown_select object for later execution of the query */
            if (!(select_lex->pushdown_select=
              new (thd->mem_root) Pushdown_select(select_lex,
                                                  select_lex->select_h)))
            {
              delete select_lex->select_h;
              select_lex->select_h= NULL;
              DBUG_RETURN(TRUE);
            }
          }
        

        With a single object it will be as simple as:

          select_lex->pushdown_select= select_lex->find_select_handler(thd);
        

        The destruction stage looks dangerous in the current implementation:

        Pushdown_select::~Pushdown_select()
        {
         if (handler->table)
           free_tmp_table(handler->thd, handler->table);
         delete handler;
         select->select_h= NULL;
        }
        

        So the server deletes a Pushdown_select instance, which then deletes the select_handler. It's much safer just to delete a single object.

      • Make it possible for the engine (e.g. XPand) to create a TABLE on its own and then reuse it during select_handler() creation time by assigning to select_handler::table. This is needed to avoid two executions of create_tmp_table() which currenly happen with XPand. So during the preparation stage, the TABLE will already be assigned to select_handler::table and select_handler will not need to make it again during the preparation stage. The method will looks about like this:

        bool select_handler::prepare()
        {
          /*
            Some engines (e.g. XPand) initialize "table" on their own.
            So we need to create a temporary table only if "table" is NULL.
          */
          if (!table && !(table= create_tmp_table(thd, select)))
            DBUG_RETURN(true);
          DBUG_RETURN(table->fill_item_list(&result_columns));
        }
        

        Notice, in the new reduction, the table is created only if select_handler::table is NULL.

      Attachments

        Issue Links

          Activity

            bar Alexander Barkov created issue -
            bar Alexander Barkov made changes -
            Field Original Value New Value
            bar Alexander Barkov made changes -
            Fix Version/s 10.5 [ 23123 ]
            Fix Version/s 10.5 [ 24012 ]
            Key TODO-2551 MDEV-23825
            Affects Version/s 10.5 [ 24012 ]
            Workflow Simple workflow [ 113929 ] MariaDB v3 [ 113930 ]
            Project Dev todo [ 10100 ] MariaDB Server [ 10000 ]
            bar Alexander Barkov made changes -
            Description Under terms of this task we'll do two things:

            - Join classes select_handler and Pushdown_select into a single class
            The current implementation with two parallel classes (select_handler and Pushdown_select) is hard to follow. Non of them can work without the other. The two-step construction stage looks too complex:
            {code:cpp}
              select_lex->select_h= select_lex->find_select_handler(thd);
              if (select_lex->select_h)
              {
                /* Create a Pushdown_select object for later execution of the query */
                if (!(select_lex->pushdown_select=
                  new (thd->mem_root) Pushdown_select(select_lex,
                                                      select_lex->select_h)))
                {
                  delete select_lex->select_h;
                  select_lex->select_h= NULL;
                  DBUG_RETURN(TRUE);
                }
              }
            {code}
            With a single object it will be as simple as:
            {code:cpp}
              select_lex->pushdown_select= select_lex->find_select_handler(thd);
            {code}
            The destruction stage looks dangerous in the current implementation:
            {code:cpp}
            Pushdown_select::~Pushdown_select()
            {
             if (handler->table)
               free_tmp_table(handler->thd, handler->table);
             delete handler;
             select->select_h= NULL;
            }
            {cpp}
            So the server deletes a Pushdown_select instance, which then deletes the select_handler. It's much safer just to delete a single object.
            - Make it possible for the engine (e.g. XPand) to create a TABLE on its own and then reuse it during select_handler() creation time by assigning to select_handler::table. This is needed to avoid two executions of create_tmp_table() which currenly happen with XPand. So during the preparation stage, the TABLE will already be assigned to select_handler::table and select_handler will not need to make it again during the preparation stage. The method will looks about like this (notice the table is created only if select_handler::table is NULL):
            {code:cpp}
            bool select_handler::prepare()
            {
              /*
                Some engines (e.g. XPand) initialize "table" on their own.
               So we need to create a temporary table only if "table" is NULL.
              */
              if (!table && !(table= create_tmp_table(thd, select)))
                DBUG_RETURN(true);
              DBUG_RETURN(table->fill_item_list(&result_columns));
            }
            {code}

            Under terms of this task we'll do two things:

            - Join classes select_handler and Pushdown_select into a single class
            The current implementation with two parallel classes (select_handler and Pushdown_select) is hard to follow. Non of them can work without the other. The two-step construction stage looks too complex:
            {code:cpp}
              select_lex->select_h= select_lex->find_select_handler(thd);
              if (select_lex->select_h)
              {
                /* Create a Pushdown_select object for later execution of the query */
                if (!(select_lex->pushdown_select=
                  new (thd->mem_root) Pushdown_select(select_lex,
                                                      select_lex->select_h)))
                {
                  delete select_lex->select_h;
                  select_lex->select_h= NULL;
                  DBUG_RETURN(TRUE);
                }
              }
            {code}
            With a single object it will be as simple as:
            {code:cpp}
              select_lex->pushdown_select= select_lex->find_select_handler(thd);
            {code}
            The destruction stage looks dangerous in the current implementation:
            {code:cpp}
            Pushdown_select::~Pushdown_select()
            {
             if (handler->table)
               free_tmp_table(handler->thd, handler->table);
             delete handler;
             select->select_h= NULL;
            }
            {code}
            So the server deletes a Pushdown_select instance, which then deletes the select_handler. It's much safer just to delete a single object.
            - Make it possible for the engine (e.g. XPand) to create a TABLE on its own and then reuse it during select_handler() creation time by assigning to select_handler::table. This is needed to avoid two executions of create_tmp_table() which currenly happen with XPand. So during the preparation stage, the TABLE will already be assigned to select_handler::table and select_handler will not need to make it again during the preparation stage. The method will looks about like this (notice the table is created only if select_handler::table is NULL):
            {code:cpp}
            bool select_handler::prepare()
            {
              /*
                Some engines (e.g. XPand) initialize "table" on their own.
               So we need to create a temporary table only if "table" is NULL.
              */
              if (!table && !(table= create_tmp_table(thd, select)))
                DBUG_RETURN(true);
              DBUG_RETURN(table->fill_item_list(&result_columns));
            }
            {code}

            bar Alexander Barkov made changes -
            Description Under terms of this task we'll do two things:

            - Join classes select_handler and Pushdown_select into a single class
            The current implementation with two parallel classes (select_handler and Pushdown_select) is hard to follow. Non of them can work without the other. The two-step construction stage looks too complex:
            {code:cpp}
              select_lex->select_h= select_lex->find_select_handler(thd);
              if (select_lex->select_h)
              {
                /* Create a Pushdown_select object for later execution of the query */
                if (!(select_lex->pushdown_select=
                  new (thd->mem_root) Pushdown_select(select_lex,
                                                      select_lex->select_h)))
                {
                  delete select_lex->select_h;
                  select_lex->select_h= NULL;
                  DBUG_RETURN(TRUE);
                }
              }
            {code}
            With a single object it will be as simple as:
            {code:cpp}
              select_lex->pushdown_select= select_lex->find_select_handler(thd);
            {code}
            The destruction stage looks dangerous in the current implementation:
            {code:cpp}
            Pushdown_select::~Pushdown_select()
            {
             if (handler->table)
               free_tmp_table(handler->thd, handler->table);
             delete handler;
             select->select_h= NULL;
            }
            {code}
            So the server deletes a Pushdown_select instance, which then deletes the select_handler. It's much safer just to delete a single object.
            - Make it possible for the engine (e.g. XPand) to create a TABLE on its own and then reuse it during select_handler() creation time by assigning to select_handler::table. This is needed to avoid two executions of create_tmp_table() which currenly happen with XPand. So during the preparation stage, the TABLE will already be assigned to select_handler::table and select_handler will not need to make it again during the preparation stage. The method will looks about like this (notice the table is created only if select_handler::table is NULL):
            {code:cpp}
            bool select_handler::prepare()
            {
              /*
                Some engines (e.g. XPand) initialize "table" on their own.
               So we need to create a temporary table only if "table" is NULL.
              */
              if (!table && !(table= create_tmp_table(thd, select)))
                DBUG_RETURN(true);
              DBUG_RETURN(table->fill_item_list(&result_columns));
            }
            {code}

            Under terms of this task we'll do two things:

            - Join classes select_handler and Pushdown_select into a single class
            The current implementation with two parallel classes (select_handler and Pushdown_select) is hard to follow. Non of them can work without the other. The two-step construction stage looks too complex:
            {code:cpp}
              select_lex->select_h= select_lex->find_select_handler(thd);
              if (select_lex->select_h)
              {
                /* Create a Pushdown_select object for later execution of the query */
                if (!(select_lex->pushdown_select=
                  new (thd->mem_root) Pushdown_select(select_lex,
                                                      select_lex->select_h)))
                {
                  delete select_lex->select_h;
                  select_lex->select_h= NULL;
                  DBUG_RETURN(TRUE);
                }
              }
            {code}
            With a single object it will be as simple as:
            {code:cpp}
              select_lex->pushdown_select= select_lex->find_select_handler(thd);
            {code}
            The destruction stage looks dangerous in the current implementation:
            {code:cpp}
            Pushdown_select::~Pushdown_select()
            {
             if (handler->table)
               free_tmp_table(handler->thd, handler->table);
             delete handler;
             select->select_h= NULL;
            }
            {code}
            So the server deletes a Pushdown_select instance, which then deletes the select_handler. It's much safer just to delete a single object.
            - Make it possible for the engine (e.g. XPand) to create a TABLE on its own and then reuse it during select_handler() creation time by assigning to select_handler::table. This is needed to avoid two executions of create_tmp_table() which currenly happen with XPand. So during the preparation stage, the TABLE will already be assigned to select_handler::table and select_handler will not need to make it again during the preparation stage. The method will looks about like this (notice the table is created only if select_handler::table is NULL):
            {code:cpp}
            bool select_handler::prepare()
            {
              /*
                Some engines (e.g. XPand) initialize "table" on their own.
                So we need to create a temporary table only if "table" is NULL.
              */
              if (!table && !(table= create_tmp_table(thd, select)))
                DBUG_RETURN(true);
              DBUG_RETURN(table->fill_item_list(&result_columns));
            }
            {code}

            bar Alexander Barkov made changes -
            Description Under terms of this task we'll do two things:

            - Join classes select_handler and Pushdown_select into a single class
            The current implementation with two parallel classes (select_handler and Pushdown_select) is hard to follow. Non of them can work without the other. The two-step construction stage looks too complex:
            {code:cpp}
              select_lex->select_h= select_lex->find_select_handler(thd);
              if (select_lex->select_h)
              {
                /* Create a Pushdown_select object for later execution of the query */
                if (!(select_lex->pushdown_select=
                  new (thd->mem_root) Pushdown_select(select_lex,
                                                      select_lex->select_h)))
                {
                  delete select_lex->select_h;
                  select_lex->select_h= NULL;
                  DBUG_RETURN(TRUE);
                }
              }
            {code}
            With a single object it will be as simple as:
            {code:cpp}
              select_lex->pushdown_select= select_lex->find_select_handler(thd);
            {code}
            The destruction stage looks dangerous in the current implementation:
            {code:cpp}
            Pushdown_select::~Pushdown_select()
            {
             if (handler->table)
               free_tmp_table(handler->thd, handler->table);
             delete handler;
             select->select_h= NULL;
            }
            {code}
            So the server deletes a Pushdown_select instance, which then deletes the select_handler. It's much safer just to delete a single object.
            - Make it possible for the engine (e.g. XPand) to create a TABLE on its own and then reuse it during select_handler() creation time by assigning to select_handler::table. This is needed to avoid two executions of create_tmp_table() which currenly happen with XPand. So during the preparation stage, the TABLE will already be assigned to select_handler::table and select_handler will not need to make it again during the preparation stage. The method will looks about like this (notice the table is created only if select_handler::table is NULL):
            {code:cpp}
            bool select_handler::prepare()
            {
              /*
                Some engines (e.g. XPand) initialize "table" on their own.
                So we need to create a temporary table only if "table" is NULL.
              */
              if (!table && !(table= create_tmp_table(thd, select)))
                DBUG_RETURN(true);
              DBUG_RETURN(table->fill_item_list(&result_columns));
            }
            {code}

            Under terms of this task we'll do two things:

            - Join classes select_handler and Pushdown_select into a single class
            The current implementation with two parallel classes (select_handler and Pushdown_select) is hard to follow. Non of them can work without the other. The two-step construction stage looks too complex:
            {code:cpp}
              select_lex->select_h= select_lex->find_select_handler(thd);
              if (select_lex->select_h)
              {
                /* Create a Pushdown_select object for later execution of the query */
                if (!(select_lex->pushdown_select=
                  new (thd->mem_root) Pushdown_select(select_lex,
                                                      select_lex->select_h)))
                {
                  delete select_lex->select_h;
                  select_lex->select_h= NULL;
                  DBUG_RETURN(TRUE);
                }
              }
            {code}
            With a single object it will be as simple as:
            {code:cpp}
              select_lex->pushdown_select= select_lex->find_select_handler(thd);
            {code}
            The destruction stage looks dangerous in the current implementation:
            {code:cpp}
            Pushdown_select::~Pushdown_select()
            {
             if (handler->table)
               free_tmp_table(handler->thd, handler->table);
             delete handler;
             select->select_h= NULL;
            }
            {code}
            So the server deletes a Pushdown_select instance, which then deletes the select_handler. It's much safer just to delete a single object.
            - Make it possible for the engine (e.g. XPand) to create a TABLE on its own and then reuse it during select_handler() creation time by assigning to select_handler::table. This is needed to avoid two executions of create_tmp_table() which currenly happen with XPand. So during the preparation stage, the TABLE will already be assigned to select_handler::table and select_handler will not need to make it again during the preparation stage. The method will looks about like this:
            {code:cpp}
            bool select_handler::prepare()
            {
              /*
                Some engines (e.g. XPand) initialize "table" on their own.
                So we need to create a temporary table only if "table" is NULL.
              */
              if (!table && !(table= create_tmp_table(thd, select)))
                DBUG_RETURN(true);
              DBUG_RETURN(table->fill_item_list(&result_columns));
            }
            {code}
            Notice, in the new reduction, the table is created only if select_handler::table is NULL.
            bar Alexander Barkov made changes -
            issue.field.resolutiondate 2020-09-27 06:35:03.0 2020-09-27 06:35:03.079
            bar Alexander Barkov made changes -
            Component/s Optimizer [ 10200 ]
            Fix Version/s 10.5.6 [ 24508 ]
            Fix Version/s 10.5 [ 23123 ]
            Resolution Fixed [ 1 ]
            Status Open [ 1 ] Closed [ 6 ]
            bar Alexander Barkov made changes -
            ralf.gebhardt Ralf Gebhardt made changes -
            Fix Version/s 10.5.7 [ 25019 ]
            ralf.gebhardt Ralf Gebhardt made changes -
            Fix Version/s 10.5.6 [ 24508 ]
            serg Sergei Golubchik made changes -
            Workflow MariaDB v3 [ 113930 ] MariaDB v4 [ 134345 ]

            People

              bar Alexander Barkov
              bar Alexander Barkov
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.