Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
4f2b786b
Commit
4f2b786b
authored
Oct 02, 2006
by
lars/lthalmann@dl145h.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/users/lthalmann/bkroot/mysql-5.1-new-rpl
into mysql.com:/users/lthalmann/bk/MERGE/mysql-5.1-merge
parents
8a5fef14
a8c9d45d
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
268 additions
and
83 deletions
+268
-83
mysql-test/extra/binlog_tests/binlog_insert_delayed.test
mysql-test/extra/binlog_tests/binlog_insert_delayed.test
+28
-14
mysql-test/include/wait_until_rows_count.inc
mysql-test/include/wait_until_rows_count.inc
+52
-0
mysql-test/r/binlog_row_binlog.result
mysql-test/r/binlog_row_binlog.result
+14
-21
mysql-test/r/binlog_statement_insert_delayed.result
mysql-test/r/binlog_statement_insert_delayed.result
+8
-11
mysql-test/r/binlog_stm_binlog.result
mysql-test/r/binlog_stm_binlog.result
+14
-21
mysql-test/r/xml.result
mysql-test/r/xml.result
+27
-1
mysql-test/t/xml.test
mysql-test/t/xml.test
+16
-0
sql/item_xmlfunc.cc
sql/item_xmlfunc.cc
+58
-6
strings/xml.c
strings/xml.c
+51
-9
No files found.
mysql-test/extra/binlog_tests/binlog_insert_delayed.test
View file @
4f2b786b
...
...
@@ -4,25 +4,39 @@ create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
set
@@
session
.
auto_increment_increment
=
1
,
@@
session
.
auto_increment_offset
=
1
;
# Verify that only one INSERT_ID event is binlogged.
# Note, that because of WL#3368 mixed mode binlog records RBR events for the delayed
let
$table
=
t1
;
let
$rows_inserted
=
11
;
# total number of inserted rows in this test
insert
delayed
into
t1
values
(
207
);
let
$count
=
1
;
# We use sleeps between statements, that's the only way to get a
# repeatable binlog in a normal test run and under Valgrind. The
# reason is that without sleeps, rows of different INSERT DELAYEDs
# sometimes group together and sometimes not, so the table may be
# unlocked/relocked causing a different number of table map log
# events.
sleep
2
;
# use this macro instead of sleeps.
--
source
include
/
wait_until_rows_count
.
inc
insert
delayed
into
t1
values
(
null
);
sleep
2
;
inc
$count
;
--
source
include
/
wait_until_rows_count
.
inc
insert
delayed
into
t1
values
(
300
);
sleep
2
;
# time for the delayed queries to reach disk
insert
delayed
into
t1
values
(
null
),(
null
),(
null
),(
null
);
sleep
2
;
insert
delayed
into
t1
values
(
null
),(
null
),(
400
),(
null
);
sleep
2
;
select
*
from
t1
;
inc
$count
;
--
source
include
/
wait_until_rows_count
.
inc
# moving binlog check affront of multi-rows queries which work is indeterministic (extra table_maps)
# todo: better check is to substitute SHOW BINLOG with reading from binlog, probably bug#19459 is in
# the way
--
replace_column
2
# 5 #
--
replace_regex
/
table_id
:
[
0
-
9
]
+/
table_id
:
#/
show
binlog
events
from
102
;
insert
delayed
into
t1
values
(
null
),(
null
),(
null
),(
null
);
inc
$count
;
inc
$count
;
inc
$count
;
inc
$count
;
--
source
include
/
wait_until_rows_count
.
inc
insert
delayed
into
t1
values
(
null
),(
null
),(
400
),(
null
);
inc
$count
;
inc
$count
;
inc
$count
;
inc
$count
;
--
source
include
/
wait_until_rows_count
.
inc
#check this assertion about $count calculation
--
echo
$count
==
$rows_inserted
select
*
from
t1
;
drop
table
t1
;
mysql-test/include/wait_until_rows_count.inc
0 → 100644
View file @
4f2b786b
# include/wait_until_rows_count.inc
# inspired by wait_for_slave_status by Matthias Leich
#
# SUMMARY
#
# Waits until SELECT count(*)-$count from $table returns zero
#
# USAGE
#
# Set vars like
# let $count=11;
# let $table=t1;
# # invoke the macro
# --include wait_until_rows_count.inc
#
# EXAMPLE
# extra/binlog/binlog_insert_delayed.test
#
#
# TODO: generalize up to wait_[until|while] with arbitrary select or even query and
# a condition to wait or get awakened
# It's impossible to implement such a "most" general macro without
# extending mysqltest. Just no way to pass a query as an argument and
# evaluate it here, like eval "$quuery". One is bound
# to specify it inside of the macro
--
disable_query_log
let
$wait_counter
=
300
;
# max wait in 0.1 seconds
while
(
$wait_counter
)
{
eval
select
count
(
*
)
-
$count
from
$table
into
@
rez
;
let
$rez
=
`select @rez`
;
let
$success
=
`SELECT @rez = 0`
;
let
$no_success
=
1
;
if
(
$success
)
{
let
$wait_counter
=
1
;
# droppping counter to leave loop
let
$no_success
=
0
;
}
if
(
$no_success
)
{
--
sleep
0.1
}
dec
$wait_counter
;
}
--
enable_query_log
if
(
$no_success
)
{
--
die
Timeout
in
wait_until_rows_count
.
inc
,
required
table
never
had
a
prescribed
number
of
rows
.
}
mysql-test/r/binlog_row_binlog.result
View file @
4f2b786b
...
...
@@ -250,8 +250,22 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
insert delayed into t1 values (207);
insert delayed into t1 values (null);
insert delayed into t1 values (300);
show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key)
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
insert delayed into t1 values (null),(null),(null),(null);
insert delayed into t1 values (null),(null),(400),(null);
11 == 11
select * from t1;
a
207
...
...
@@ -265,25 +279,4 @@ a
306
400
401
show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key)
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
drop table t1;
mysql-test/r/binlog_statement_insert_delayed.result
View file @
4f2b786b
...
...
@@ -3,8 +3,16 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
insert delayed into t1 values (207);
insert delayed into t1 values (null);
insert delayed into t1 values (300);
show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (207)
master-bin.000001 # Intvar 1 # INSERT_ID=208
master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null)
master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (300)
insert delayed into t1 values (null),(null),(null),(null);
insert delayed into t1 values (null),(null),(400),(null);
11 == 11
select * from t1;
a
207
...
...
@@ -18,15 +26,4 @@ a
306
400
401
show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (207)
master-bin.000001 # Intvar 1 # INSERT_ID=208
master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null)
master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (300)
master-bin.000001 # Intvar 1 # INSERT_ID=301
master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null),(null),(null),(null)
master-bin.000001 # Intvar 1 # INSERT_ID=305
master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null),(null),(400),(null)
drop table t1;
mysql-test/r/binlog_stm_binlog.result
View file @
4f2b786b
...
...
@@ -160,8 +160,22 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
insert delayed into t1 values (207);
insert delayed into t1 values (null);
insert delayed into t1 values (300);
show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key)
master-bin.000001 # Intvar 1 # INSERT_ID=127
master-bin.000001 # Query 1 # use `test`; insert into t1 values(null)
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
insert delayed into t1 values (null),(null),(null),(null);
insert delayed into t1 values (null),(null),(400),(null);
11 == 11
select * from t1;
a
207
...
...
@@ -175,25 +189,4 @@ a
306
400
401
show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key)
master-bin.000001 # Intvar 1 # INSERT_ID=127
master-bin.000001 # Query 1 # use `test`; insert into t1 values(null)
master-bin.000001 # Query 1 # use `test`; drop table t1
master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map 1 # table_id: # (test.t1)
master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
drop table t1;
mysql-test/r/xml.result
View file @
4f2b786b
...
...
@@ -570,7 +570,7 @@ select extractvalue('<a>a<b>B</b></a>','a|/b');
extractvalue('<a>a<b>B</b></a>','a|/b')
a
select extractvalue('<a>A</a>','/<a>');
ERROR HY000: XPATH
syntax error
: '<a>'
ERROR HY000: XPATH
error: comparison of two nodesets is not supported
: '<a>'
select extractvalue('<a><b>b</b><b!>b!</b!></a>','//b!');
ERROR HY000: XPATH syntax error: '!'
select extractvalue('<a>A<b>B<c>C</c></b></a>','/a/descendant::*');
...
...
@@ -710,3 +710,29 @@ Data
select extractValue('<foo><foo.bar>Data</foo.bar><something>Otherdata</something></foo>','/foo/something');
extractValue('<foo><foo.bar>Data</foo.bar><something>Otherdata</something></foo>','/foo/something')
Otherdata
select extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','/zot/tim0/02');
ERROR HY000: XPATH syntax error: '02'
select extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','//*');
extractValue('<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>','//*')
NULL
Warnings:
Warning 1512 Incorrect XML value: 'parse error at line 1 pos 13: unknown token unexpected (ident or '/' wanted)'
select extractValue('<.>test</.>','//*');
extractValue('<.>test</.>','//*')
NULL
Warnings:
Warning 1512 Incorrect XML value: 'parse error at line 1 pos 2: unknown token unexpected (ident or '/' wanted)'
select extractValue('<->test</->','//*');
extractValue('<->test</->','//*')
NULL
Warnings:
Warning 1512 Incorrect XML value: 'parse error at line 1 pos 2: unknown token unexpected (ident or '/' wanted)'
select extractValue('<:>test</:>','//*');
extractValue('<:>test</:>','//*')
test
select extractValue('<_>test</_>','//*');
extractValue('<_>test</_>','//*')
test
select extractValue('<x.-_:>test</x.-_:>','//*');
extractValue('<x.-_:>test</x.-_:>','//*')
test
mysql-test/t/xml.test
View file @
4f2b786b
...
...
@@ -360,3 +360,19 @@ select extractValue('<ns:element xmlns:ns="myns">a</ns:element>','/ns:element/@x
#
select
extractValue
(
'<foo><foo.bar>Data</foo.bar><something>Otherdata</something></foo>'
,
'/foo/foo.bar'
);
select
extractValue
(
'<foo><foo.bar>Data</foo.bar><something>Otherdata</something></foo>'
,
'/foo/something'
);
#
# Bug#20854 XML functions: wrong result in ExtractValue
#
--
error
1105
select
extractValue
(
'<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>'
,
'/zot/tim0/02'
);
select
extractValue
(
'<zot><tim0><01>10:39:15</01><02>140</02></tim0></zot>'
,
'//*'
);
# dot and dash are bad identtifier start character
select
extractValue
(
'<.>test</.>'
,
'//*'
);
select
extractValue
(
'<->test</->'
,
'//*'
);
# semicolon is good identifier start character
select
extractValue
(
'<:>test</:>'
,
'//*'
);
# underscore is good identifier start character
select
extractValue
(
'<_>test</_>'
,
'//*'
);
# dot, dash, underscore and semicolon are good identifier middle characters
select
extractValue
(
'<x.-_:>test</x.-_:>'
,
'//*'
);
sql/item_xmlfunc.cc
View file @
4f2b786b
...
...
@@ -105,6 +105,7 @@ typedef struct my_xpath_st
String
*
context_cache
;
/* last context provider */
String
*
pxml
;
/* Parsed XML, an array of MY_XML_NODE */
CHARSET_INFO
*
cs
;
/* character set/collation string comparison */
int
error
;
}
MY_XPATH
;
...
...
@@ -913,7 +914,9 @@ static Item *eq_func_reverse(int oper, Item *a, Item *b)
RETURN
The newly created item.
*/
static
Item
*
create_comparator
(
MY_XPATH
*
xpath
,
int
oper
,
Item
*
a
,
Item
*
b
)
static
Item
*
create_comparator
(
MY_XPATH
*
xpath
,
int
oper
,
MY_XPATH_LEX
*
context
,
Item
*
a
,
Item
*
b
)
{
if
(
a
->
type
()
!=
Item
::
XPATH_NODESET
&&
b
->
type
()
!=
Item
::
XPATH_NODESET
)
...
...
@@ -923,6 +926,13 @@ static Item *create_comparator(MY_XPATH *xpath, int oper, Item *a, Item *b)
else
if
(
a
->
type
()
==
Item
::
XPATH_NODESET
&&
b
->
type
()
==
Item
::
XPATH_NODESET
)
{
uint
len
=
context
->
end
-
context
->
beg
;
set_if_bigger
(
len
,
32
);
my_printf_error
(
ER_UNKNOWN_ERROR
,
"XPATH error: "
"comparison of two nodesets is not supported: '%.*s'"
,
MYF
(
0
),
len
,
context
->
beg
);
return
0
;
// TODO: Comparison of two nodesets
}
else
...
...
@@ -1430,7 +1440,7 @@ my_xpath_lex_scan(MY_XPATH *xpath,
static
int
my_xpath_parse_term
(
MY_XPATH
*
xpath
,
int
term
)
{
if
(
xpath
->
lasttok
.
term
==
term
)
if
(
xpath
->
lasttok
.
term
==
term
&&
!
xpath
->
error
)
{
xpath
->
prevtok
=
xpath
->
lasttok
;
my_xpath_lex_scan
(
xpath
,
&
xpath
->
lasttok
,
...
...
@@ -1558,8 +1568,9 @@ static int my_xpath_parse_AbsoluteLocationPath(MY_XPATH *xpath)
return
my_xpath_parse_RelativeLocationPath
(
xpath
);
}
return
my_xpath_parse_term
(
xpath
,
MY_XPATH_LEX_EOF
)
||
my_xpath_parse_RelativeLocationPath
(
xpath
);
return
(
xpath
->
error
==
0
);
}
...
...
@@ -1596,8 +1607,11 @@ static int my_xpath_parse_RelativeLocationPath(MY_XPATH *xpath)
"*"
,
1
,
xpath
->
pxml
,
1
);
if
(
!
my_xpath_parse_Step
(
xpath
))
{
xpath
->
error
=
1
;
return
0
;
}
}
return
1
;
}
...
...
@@ -1633,10 +1647,16 @@ my_xpath_parse_AxisSpecifier_NodeTest_opt_Predicate_list(MY_XPATH *xpath)
xpath
->
context_cache
=
context_cache
;
if
(
!
my_xpath_parse_PredicateExpr
(
xpath
))
{
xpath
->
error
=
1
;
return
0
;
}
if
(
!
my_xpath_parse_term
(
xpath
,
MY_XPATH_LEX_RB
))
{
xpath
->
error
=
1
;
return
0
;
}
xpath
->
item
=
nodeset2bool
(
xpath
,
xpath
->
item
);
...
...
@@ -1893,7 +1913,10 @@ static int my_xpath_parse_UnionExpr(MY_XPATH *xpath)
if
(
!
my_xpath_parse_PathExpr
(
xpath
)
||
xpath
->
item
->
type
()
!=
Item
::
XPATH_NODESET
)
{
xpath
->
error
=
1
;
return
0
;
}
xpath
->
item
=
new
Item_nodeset_func_union
(
prev
,
xpath
->
item
,
xpath
->
pxml
);
}
return
1
;
...
...
@@ -1929,6 +1952,7 @@ static int my_xpath_parse_PathExpr(MY_XPATH *xpath)
{
return
my_xpath_parse_LocationPath
(
xpath
)
||
my_xpath_parse_FilterExpr_opt_slashes_RelativeLocationPath
(
xpath
);
}
...
...
@@ -1975,7 +1999,10 @@ static int my_xpath_parse_OrExpr(MY_XPATH *xpath)
{
Item
*
prev
=
xpath
->
item
;
if
(
!
my_xpath_parse_AndExpr
(
xpath
))
{
return
0
;
xpath
->
error
=
1
;
}
xpath
->
item
=
new
Item_cond_or
(
nodeset2bool
(
xpath
,
prev
),
nodeset2bool
(
xpath
,
xpath
->
item
));
}
...
...
@@ -2003,7 +2030,10 @@ static int my_xpath_parse_AndExpr(MY_XPATH *xpath)
{
Item
*
prev
=
xpath
->
item
;
if
(
!
my_xpath_parse_EqualityExpr
(
xpath
))
{
xpath
->
error
=
1
;
return
0
;
}
xpath
->
item
=
new
Item_cond_and
(
nodeset2bool
(
xpath
,
prev
),
nodeset2bool
(
xpath
,
xpath
->
item
));
...
...
@@ -2057,17 +2087,26 @@ static int my_xpath_parse_EqualityOperator(MY_XPATH *xpath)
}
static
int
my_xpath_parse_EqualityExpr
(
MY_XPATH
*
xpath
)
{
MY_XPATH_LEX
operator_context
;
if
(
!
my_xpath_parse_RelationalExpr
(
xpath
))
return
0
;
operator_context
=
xpath
->
lasttok
;
while
(
my_xpath_parse_EqualityOperator
(
xpath
))
{
Item
*
prev
=
xpath
->
item
;
int
oper
=
xpath
->
extra
;
if
(
!
my_xpath_parse_RelationalExpr
(
xpath
))
{
xpath
->
error
=
1
;
return
0
;
}
if
(
!
(
xpath
->
item
=
create_comparator
(
xpath
,
oper
,
prev
,
xpath
->
item
)))
if
(
!
(
xpath
->
item
=
create_comparator
(
xpath
,
oper
,
&
operator_context
,
prev
,
xpath
->
item
)))
return
0
;
operator_context
=
xpath
->
lasttok
;
}
return
1
;
}
...
...
@@ -2109,18 +2148,25 @@ static int my_xpath_parse_RelationalOperator(MY_XPATH *xpath)
}
static
int
my_xpath_parse_RelationalExpr
(
MY_XPATH
*
xpath
)
{
MY_XPATH_LEX
operator_context
;
if
(
!
my_xpath_parse_AdditiveExpr
(
xpath
))
return
0
;
operator_context
=
xpath
->
lasttok
;
while
(
my_xpath_parse_RelationalOperator
(
xpath
))
{
Item
*
prev
=
xpath
->
item
;
int
oper
=
xpath
->
extra
;
if
(
!
my_xpath_parse_AdditiveExpr
(
xpath
))
{
xpath
->
error
=
1
;
return
0
;
}
if
(
!
(
xpath
->
item
=
create_comparator
(
xpath
,
oper
,
prev
,
xpath
->
item
)))
if
(
!
(
xpath
->
item
=
create_comparator
(
xpath
,
oper
,
&
operator_context
,
prev
,
xpath
->
item
)))
return
0
;
operator_context
=
xpath
->
lasttok
;
}
return
1
;
}
...
...
@@ -2153,7 +2199,10 @@ static int my_xpath_parse_AdditiveExpr(MY_XPATH *xpath)
int
oper
=
xpath
->
prevtok
.
term
;
Item
*
prev
=
xpath
->
item
;
if
(
!
my_xpath_parse_MultiplicativeExpr
(
xpath
))
{
xpath
->
error
=
1
;
return
0
;
}
if
(
oper
==
MY_XPATH_LEX_PLUS
)
xpath
->
item
=
new
Item_func_plus
(
prev
,
xpath
->
item
);
...
...
@@ -2198,7 +2247,10 @@ static int my_xpath_parse_MultiplicativeExpr(MY_XPATH *xpath)
int
oper
=
xpath
->
prevtok
.
term
;
Item
*
prev
=
xpath
->
item
;
if
(
!
my_xpath_parse_UnaryExpr
(
xpath
))
{
xpath
->
error
=
1
;
return
0
;
}
switch
(
oper
)
{
case
MY_XPATH_LEX_ASTERISK
:
...
...
strings/xml.c
View file @
4f2b786b
...
...
@@ -19,6 +19,7 @@
#include "my_xml.h"
#define MY_XML_UNKNOWN 'U'
#define MY_XML_EOF 'E'
#define MY_XML_STRING 'S'
#define MY_XML_IDENT 'I'
...
...
@@ -39,6 +40,46 @@ typedef struct xml_attr_st
}
MY_XML_ATTR
;
/*
XML ctype:
*/
#define MY_XML_ID0 0x01
/* Identifier initial character */
#define MY_XML_ID1 0x02
/* Identifier medial character */
#define MY_XML_SPC 0x08
/* Spacing character */
/*
http://www.w3.org/TR/REC-xml/
[4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
CombiningChar | Extender
[5] Name ::= (Letter | '_' | ':') (NameChar)*
*/
static
char
my_xml_ctype
[
256
]
=
{
/*00*/
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
8
,
8
,
0
,
0
,
8
,
0
,
0
,
/*10*/
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
/*20*/
8
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
2
,
2
,
0
,
/* !"#$%&'()*+,-./ */
/*30*/
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
2
,
3
,
0
,
0
,
0
,
0
,
0
,
/* 0123456789:;<=>? */
/*40*/
0
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
/* @ABCDEFGHIJKLMNO */
/*50*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
0
,
0
,
0
,
0
,
3
,
/* PQRSTUVWXYZ[\]^_ */
/*60*/
0
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
/* `abcdefghijklmno */
/*70*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
0
,
0
,
0
,
0
,
0
,
/* pqrstuvwxyz{|}~ */
/*80*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
/*90*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
/*A0*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
/*B0*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
/*C0*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
/*D0*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
/*E0*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
/*F0*/
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
,
3
};
#define my_xml_is_space(c) (my_xml_ctype[(uchar) (c)] & MY_XML_SPC)
#define my_xml_is_id0(c) (my_xml_ctype[(uchar) (c)] & MY_XML_ID0)
#define my_xml_is_id1(c) (my_xml_ctype[(uchar) (c)] & MY_XML_ID1)
static
const
char
*
lex2str
(
int
lex
)
{
switch
(
lex
)
...
...
@@ -56,13 +97,13 @@ static const char *lex2str(int lex)
case
MY_XML_QUESTION
:
return
"'?'"
;
case
MY_XML_EXCLAM
:
return
"'!'"
;
}
return
"
UNKNOWN
"
;
return
"
unknown token
"
;
}
static
void
my_xml_norm_text
(
MY_XML_ATTR
*
a
)
{
for
(
;
(
a
->
beg
<
a
->
end
)
&&
strchr
(
"
\t\r\n
"
,
a
->
beg
[
0
])
;
a
->
beg
++
);
for
(
;
(
a
->
beg
<
a
->
end
)
&&
strchr
(
"
\t\r\n
"
,
a
->
end
[
-
1
])
;
a
->
end
--
);
for
(
;
(
a
->
beg
<
a
->
end
)
&&
my_xml_is_space
(
a
->
beg
[
0
])
;
a
->
beg
++
);
for
(
;
(
a
->
beg
<
a
->
end
)
&&
my_xml_is_space
(
a
->
end
[
-
1
])
;
a
->
end
--
);
}
...
...
@@ -70,7 +111,7 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a)
{
int
lex
;
for
(
;
(
p
->
cur
<
p
->
end
)
&&
strchr
(
"
\t\r\n
"
,
p
->
cur
[
0
])
;
p
->
cur
++
);
for
(
;
(
p
->
cur
<
p
->
end
)
&&
my_xml_is_space
(
p
->
cur
[
0
])
;
p
->
cur
++
);
if
(
p
->
cur
>=
p
->
end
)
{
...
...
@@ -124,16 +165,17 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a)
my_xml_norm_text
(
a
);
lex
=
MY_XML_STRING
;
}
else
else
if
(
my_xml_is_id0
(
p
->
cur
[
0
]))
{
for
(;
(
p
->
cur
<
p
->
end
)
&&
!
strchr
(
"?'
\"
=/<>
\t\r\n
"
,
p
->
cur
[
0
]);
p
->
cur
++
)
{}
p
->
cur
++
;
while
(
p
->
cur
<
p
->
end
&&
my_xml_is_id1
(
p
->
cur
[
0
]))
p
->
cur
++
;
a
->
end
=
p
->
cur
;
my_xml_norm_text
(
a
);
lex
=
MY_XML_IDENT
;
}
else
lex
=
MY_XML_UNKNOWN
;
#if 0
printf("LEX=%s[%d]\n",lex2str(lex),a->end-a->beg);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment