mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-04 04:46:15 +01:00 
			
		
		
		
	The `Item` class methods `get_copy()`, `build_clone()`, and `clone_item()` face an issue where they may be defined in a descendant class (e.g., `Item_func`) but not in a further descendant (e.g., `Item_func_child`). This can lead to scenarios where `build_clone()`, when operating on an instance of `Item_func_child` with a pointer to the base class (`Item`), returns an instance of `Item_func` instead of `Item_func_child`. Since this limitation cannot be resolved at compile time, this commit introduces runtime type checks for the copy/clone operations. A debug assertion will now trigger in case of a type mismatch. `get_copy()`, `build_clone()`, and `clone_item()` are no more virtual, but virtual `do_get_copy()`, `do_build_clone()`, and `do_clone_item()` are added to the protected section of the class `Item`. Additionally, const qualifiers have been added to certain methods to enhance code reliability. Reviewer: Oleksandr Byelkin <sanja@mariadb.com>
		
			
				
	
	
		
			157 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			157 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef ITEM_XMLFUNC_INCLUDED
 | 
						|
#define ITEM_XMLFUNC_INCLUDED
 | 
						|
 | 
						|
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
 | 
						|
   Copyright (c) 2009, 2019, MariaDB
 | 
						|
 | 
						|
   This program is free software; you can redistribute it and/or modify
 | 
						|
   it under the terms of the GNU General Public License as published by
 | 
						|
   the Free Software Foundation; version 2 of the License.
 | 
						|
 | 
						|
   This program is distributed in the hope that it will be useful,
 | 
						|
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
   GNU General Public License for more details.
 | 
						|
 | 
						|
   You should have received a copy of the GNU General Public License
 | 
						|
   along with this program; if not, write to the Free Software
 | 
						|
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
 | 
						|
 | 
						|
 | 
						|
/* This file defines all XML functions */
 | 
						|
 | 
						|
 | 
						|
typedef struct my_xml_node_st MY_XML_NODE;
 | 
						|
 | 
						|
 | 
						|
/* Structure to store nodeset elements */
 | 
						|
class MY_XPATH_FLT
 | 
						|
{
 | 
						|
public:
 | 
						|
  uint num;     // Absolute position in MY_XML_NODE array
 | 
						|
  uint pos;     // Relative position in context
 | 
						|
  uint size;    // Context size
 | 
						|
public:
 | 
						|
  MY_XPATH_FLT(uint32 num_arg, uint32 pos_arg)
 | 
						|
   :num(num_arg), pos(pos_arg), size(0)
 | 
						|
  { }
 | 
						|
  MY_XPATH_FLT(uint32 num_arg, uint32 pos_arg, uint32 size_arg)
 | 
						|
   :num(num_arg), pos(pos_arg), size(size_arg)
 | 
						|
  { }
 | 
						|
  bool append_to(Native *to) const
 | 
						|
  {
 | 
						|
    return to->append((const char*) this, (uint32) sizeof(*this));
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class NativeNodesetBuffer: public NativeBuffer<16*sizeof(MY_XPATH_FLT)>
 | 
						|
{
 | 
						|
public:
 | 
						|
  const MY_XPATH_FLT &element(uint i) const
 | 
						|
  {
 | 
						|
    const MY_XPATH_FLT *p= (MY_XPATH_FLT*) (ptr() + i * sizeof(MY_XPATH_FLT));
 | 
						|
    return *p;
 | 
						|
  }
 | 
						|
  uint32 elements() const
 | 
						|
  {
 | 
						|
    return length() / sizeof(MY_XPATH_FLT);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class Item_xml_str_func: public Item_str_func
 | 
						|
{
 | 
						|
protected:
 | 
						|
  /*
 | 
						|
    A helper class to store raw and parsed XML.
 | 
						|
  */
 | 
						|
  class XML
 | 
						|
  {
 | 
						|
    bool m_cached;
 | 
						|
    String *m_raw_ptr;   // Pointer to text representation
 | 
						|
    String m_raw_buf;    // Cached text representation
 | 
						|
    String m_parsed_buf; // Array of MY_XML_NODEs, pointing to raw_buffer
 | 
						|
    bool parse();
 | 
						|
    void reset()
 | 
						|
    {
 | 
						|
      m_cached= false;
 | 
						|
      m_raw_ptr= (String *) 0;
 | 
						|
    }
 | 
						|
  public:
 | 
						|
    XML() { reset(); }
 | 
						|
    void set_charset(CHARSET_INFO *cs) { m_parsed_buf.set_charset(cs); }
 | 
						|
    String *raw() { return m_raw_ptr; }
 | 
						|
    String *parsed() { return &m_parsed_buf; }
 | 
						|
    const MY_XML_NODE *node(uint idx);
 | 
						|
    bool cached() { return m_cached; }
 | 
						|
    bool parse(String *raw, bool cache);
 | 
						|
    bool parse(Item *item, bool cache)
 | 
						|
    {
 | 
						|
      String *res;
 | 
						|
      if (!(res= item->val_str(&m_raw_buf)))
 | 
						|
      {
 | 
						|
        m_raw_ptr= (String *) 0;
 | 
						|
        m_cached= cache;
 | 
						|
        return true;
 | 
						|
      }
 | 
						|
      return parse(res, cache);
 | 
						|
    }
 | 
						|
  };
 | 
						|
  String m_xpath_query; // XPath query text
 | 
						|
  Item *nodeset_func;
 | 
						|
  XML xml;
 | 
						|
  bool get_xml(XML *xml_arg, bool cache= false)
 | 
						|
  {
 | 
						|
    if (!cache && xml_arg->cached())
 | 
						|
      return xml_arg->raw() == 0;
 | 
						|
    return xml_arg->parse(args[0], cache);
 | 
						|
  }
 | 
						|
public:
 | 
						|
  Item_xml_str_func(THD *thd, Item *a, Item *b): Item_str_func(thd, a, b)
 | 
						|
  {
 | 
						|
    maybe_null= TRUE;
 | 
						|
  }
 | 
						|
  Item_xml_str_func(THD *thd, Item *a, Item *b, Item *c):
 | 
						|
    Item_str_func(thd, a, b, c)
 | 
						|
  {
 | 
						|
    maybe_null= TRUE;
 | 
						|
  }
 | 
						|
  bool fix_fields(THD *thd, Item **ref) override;
 | 
						|
  bool fix_length_and_dec() override;
 | 
						|
  bool const_item() const override
 | 
						|
  {
 | 
						|
    return const_item_cache && (!nodeset_func || nodeset_func->const_item());
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class Item_func_xml_extractvalue: public Item_xml_str_func
 | 
						|
{
 | 
						|
public:
 | 
						|
  Item_func_xml_extractvalue(THD *thd, Item *a, Item *b):
 | 
						|
    Item_xml_str_func(thd, a, b) {}
 | 
						|
  const char *func_name() const override { return "extractvalue"; }
 | 
						|
  String *val_str(String *) override;
 | 
						|
  Item *do_get_copy(THD *thd) const override
 | 
						|
  { return get_item_copy<Item_func_xml_extractvalue>(thd, this); }
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class Item_func_xml_update: public Item_xml_str_func
 | 
						|
{
 | 
						|
  NativeNodesetBuffer tmp_native_value2;
 | 
						|
  String tmp_value3;
 | 
						|
  bool collect_result(String *str,
 | 
						|
                      const MY_XML_NODE *cut,
 | 
						|
                      const String *replace);
 | 
						|
public:
 | 
						|
  Item_func_xml_update(THD *thd, Item *a, Item *b, Item *c):
 | 
						|
    Item_xml_str_func(thd, a, b, c) {}
 | 
						|
  const char *func_name() const override { return "updatexml"; }
 | 
						|
  String *val_str(String *) override;
 | 
						|
  Item *do_get_copy(THD *thd) const override
 | 
						|
  { return get_item_copy<Item_func_xml_update>(thd, this); }
 | 
						|
};
 | 
						|
 | 
						|
#endif /* ITEM_XMLFUNC_INCLUDED */
 |