diff options
author | unknown <bar@bar.myoffice.izhnet.ru> | 2007-10-30 12:03:34 +0400 |
---|---|---|
committer | unknown <bar@bar.myoffice.izhnet.ru> | 2007-10-30 12:03:34 +0400 |
commit | a3b60d2d5177f48ca82ef644e81f5b287b52f1ba (patch) | |
tree | 055f7dd7e7eb9e1550d06cb68db95e06cebefffd /sql/item_xmlfunc.cc | |
parent | 7d9c59b7be412210413fc93602ec4522eb1f368b (diff) | |
parent | e70e5326747fc09819c0ba6c82b781248f66495f (diff) | |
download | mariadb-git-a3b60d2d5177f48ca82ef644e81f5b287b52f1ba.tar.gz |
Merge abarkov@bk-internal.mysql.com:/home/bk/mysql-5.1
into mysql.com:/home/bar/mysql-work/mysql-5.1-new-rpl-merge
client/mysql.cc:
Auto merged
mysql-test/r/ctype_euckr.result:
Auto merged
mysql-test/r/ctype_uca.result:
Auto merged
mysql-test/r/ctype_utf8.result:
Auto merged
mysql-test/r/func_regexp.result:
Auto merged
mysql-test/suite/rpl/r/rpl_bug31076.result:
Auto merged
mysql-test/t/ctype_utf8.test:
Auto merged
mysql-test/t/func_regexp.test:
Auto merged
mysql-test/t/partition.test:
Auto merged
sql/field.cc:
Auto merged
sql/field.h:
Auto merged
sql/handler.cc:
Auto merged
sql/item_cmpfunc.cc:
Auto merged
sql/item_cmpfunc.h:
Auto merged
sql/item_xmlfunc.cc:
Auto merged
sql/log.cc:
Auto merged
sql/log.h:
Auto merged
sql/log_event.cc:
Auto merged
sql/mysqld.cc:
Auto merged
sql/sp_head.cc:
Auto merged
sql/sql_class.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_delete.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_repl.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_update.cc:
Auto merged
strings/ctype-euc_kr.c:
Auto merged
sql/sql_yacc.yy:
Reverting Rafal's changes: TRANSACTIONAL_SYM was removed in a mistake.
mysql-test/r/ctype_ucs.result:
After merge fix
mysql-test/suite/rpl/t/rpl_bug31076.test:
After merge fix.
mysql-test/t/ctype_ucs.test:
After megre fix
Diffstat (limited to 'sql/item_xmlfunc.cc')
-rw-r--r-- | sql/item_xmlfunc.cc | 60 |
1 files changed, 24 insertions, 36 deletions
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 1a6c15a4d2e..68d85418324 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2612,35 +2612,27 @@ typedef struct uint level; String *pxml; // parsed XML uint pos[MAX_LEVEL]; // Tag position stack + uint parent; // Offset of the parent of the current node } MY_XML_USER_DATA; -/* - Find the parent node - - SYNOPSYS - Find the parent node, i.e. a tag or attrubute node on the given level. - - RETURN - 1 - success - 0 - failure -*/ -static uint xml_parent_tag(MY_XML_NODE *items, uint nitems, uint level) +static bool +append_node(String *str, MY_XML_NODE *node) { - if (!nitems) - return 0; - - MY_XML_NODE *p, *last= &items[nitems-1]; - for (p= last; p >= items; p--) - { - if (p->level == level && - (p->type == MY_XML_NODE_TAG || - p->type == MY_XML_NODE_ATTR)) - { - return p - items; - } - } - return 0; + /* + If "str" doesn't have space for a new node, + it will allocate two times more space that it has had so far. + (2*len+512) is a heuristic value, + which gave the best performance during tests. + The ideas behind this formula are: + - It allows to have a very small number of reallocs: + about 10 reallocs on a 1Mb-long XML value. + - At the same time, it avoids excessive memory use. + */ + if (str->reserve(sizeof(MY_XML_NODE), 2 * str->length() + 512)) + return TRUE; + str->q_append((const char*) node, sizeof(MY_XML_NODE)); + return FALSE; } @@ -2662,19 +2654,17 @@ extern "C" int xml_enter(MY_XML_PARSER *st,const char *attr, size_t len); int xml_enter(MY_XML_PARSER *st,const char *attr, size_t len) { MY_XML_USER_DATA *data= (MY_XML_USER_DATA*)st->user_data; - MY_XML_NODE *nodes= (MY_XML_NODE*) data->pxml->ptr(); uint numnodes= data->pxml->length() / sizeof(MY_XML_NODE); - uint parent= xml_parent_tag(nodes, numnodes, data->level - 1); MY_XML_NODE node; + node.parent= data->parent; // Set parent for the new node to old parent + data->parent= numnodes; // Remember current node as new parent data->pos[data->level]= numnodes; node.level= data->level++; node.type= st->current_node_type; // TAG or ATTR node.beg= attr; node.end= attr + len; - node.parent= parent; - data->pxml->append((const char*) &node, sizeof(MY_XML_NODE)); - return MY_XML_OK; + return append_node(data->pxml, &node) ? MY_XML_ERROR : MY_XML_OK; } @@ -2695,18 +2685,14 @@ extern "C" int xml_value(MY_XML_PARSER *st,const char *attr, size_t len); int xml_value(MY_XML_PARSER *st,const char *attr, size_t len) { MY_XML_USER_DATA *data= (MY_XML_USER_DATA*)st->user_data; - MY_XML_NODE *nodes= (MY_XML_NODE*) data->pxml->ptr(); - uint numnodes= data->pxml->length() / sizeof(MY_XML_NODE); - uint parent= xml_parent_tag(nodes, numnodes, data->level - 1); MY_XML_NODE node; + node.parent= data->parent; // Set parent for the new text node to old parent node.level= data->level; node.type= MY_XML_NODE_TEXT; node.beg= attr; node.end= attr + len; - node.parent= parent; - data->pxml->append((const char*) &node, sizeof(MY_XML_NODE)); - return MY_XML_OK; + return append_node(data->pxml, &node) ? MY_XML_ERROR : MY_XML_OK; } @@ -2731,6 +2717,7 @@ int xml_leave(MY_XML_PARSER *st,const char *attr, size_t len) data->level--; MY_XML_NODE *nodes= (MY_XML_NODE*) data->pxml->ptr(); + data->parent= nodes[data->parent].parent; nodes+= data->pos[data->level]; nodes->tagend= st->cur; @@ -2761,6 +2748,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf) p.flags= MY_XML_FLAG_RELATIVE_NAMES | MY_XML_FLAG_SKIP_TEXT_NORMALIZATION; user_data.level= 0; user_data.pxml= parsed_xml_buf; + user_data.parent= 0; my_xml_set_enter_handler(&p, xml_enter); my_xml_set_value_handler(&p, xml_value); my_xml_set_leave_handler(&p, xml_leave); |