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
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
523ef2a1
Commit
523ef2a1
authored
Aug 05, 2024
by
Vladislav Vaintroub
Browse files
Options
Browse Files
Download
Plain Diff
Merge 11.5 into 11.6
parents
c175f498
06a7352d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
254 additions
and
209 deletions
+254
-209
include/m_ctype.h
include/m_ctype.h
+46
-0
mysql-test/main/tmp_table_count-7586.result
mysql-test/main/tmp_table_count-7586.result
+5
-15
mysql-test/main/tmp_table_count-7586.test
mysql-test/main/tmp_table_count-7586.test
+5
-5
sql/lex_ident_cli.h
sql/lex_ident_cli.h
+122
-0
sql/lex_ident_sys.h
sql/lex_ident_sys.h
+75
-0
sql/sql_lex.h
sql/sql_lex.h
+1
-147
sql/sql_string.h
sql/sql_string.h
+0
-42
No files found.
include/m_ctype.h
View file @
523ef2a1
...
...
@@ -1932,6 +1932,52 @@ my_strcasecmp_latin1(const char *a, const char *b)
int
my_wc_mb_utf8mb4_bmp_only
(
CHARSET_INFO
*
cs
,
my_wc_t
wc
,
uchar
*
r
,
uchar
*
e
);
#ifdef __cplusplus
class
String_copy_status
:
protected
MY_STRCOPY_STATUS
{
public:
const
char
*
source_end_pos
()
const
{
return
m_source_end_pos
;
}
const
char
*
well_formed_error_pos
()
const
{
return
m_well_formed_error_pos
;
}
};
class
Well_formed_prefix_status
:
public
String_copy_status
{
public:
Well_formed_prefix_status
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
const
char
*
end
,
size_t
nchars
)
{
cs
->
well_formed_char_length
(
str
,
end
,
nchars
,
this
);
}
};
class
Well_formed_prefix
:
public
Well_formed_prefix_status
{
const
char
*
m_str
;
// The beginning of the string
public:
Well_formed_prefix
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
const
char
*
end
,
size_t
nchars
)
:
Well_formed_prefix_status
(
cs
,
str
,
end
,
nchars
),
m_str
(
str
)
{
}
Well_formed_prefix
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
size_t
length
,
size_t
nchars
)
:
Well_formed_prefix_status
(
cs
,
str
,
str
+
length
,
nchars
),
m_str
(
str
)
{
}
Well_formed_prefix
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
size_t
length
)
:
Well_formed_prefix_status
(
cs
,
str
,
str
+
length
,
length
),
m_str
(
str
)
{
}
Well_formed_prefix
(
CHARSET_INFO
*
cs
,
LEX_CSTRING
str
,
size_t
nchars
)
:
Well_formed_prefix_status
(
cs
,
str
.
str
,
str
.
str
+
str
.
length
,
nchars
),
m_str
(
str
.
str
)
{
}
size_t
length
()
const
{
return
m_source_end_pos
-
m_str
;
}
};
#endif
/* __cplusplus */
#ifdef __cplusplus
}
#endif
...
...
mysql-test/main/tmp_table_count-7586.result
View file @
523ef2a1
...
...
@@ -7,10 +7,8 @@ a
1
2
3
show status like '%Created_tmp%';
show status like '%Created_tmp
_tables
%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
explain select * from v2;
id select_type table type possible_keys key key_len ref rows Extra
...
...
@@ -20,10 +18,8 @@ a
1
2
3
show status like '%Created_tmp%';
show status like '%Created_tmp
_tables
%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
explain select * from (select * from t2) T1;
id select_type table type possible_keys key key_len ref rows Extra
...
...
@@ -46,10 +42,8 @@ CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING
select sum(created_tmp_tables) from performance_schema.events_statements_history_long;
sum(created_tmp_tables)
2
show status like '%Created_tmp%';
show status like '%Created_tmp
_tables
%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 2
drop table t3;
set @@optimizer_switch="firstmatch=off";
...
...
@@ -65,10 +59,8 @@ CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a);
select sum(created_tmp_tables) from performance_schema.events_statements_history_long;
sum(created_tmp_tables)
1
show status like '%Created_tmp%';
show status like '%Created_tmp
_tables
%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 1
set @@optimizer_switch=default;
drop table t1,t2,t3;
...
...
@@ -78,8 +70,6 @@ flush status;
select sum(created_tmp_tables) from performance_schema.events_statements_history_long;
sum(created_tmp_tables)
0
show status like '%Created_tmp%';
show status like '%Created_tmp
_tables
%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
mysql-test/main/tmp_table_count-7586.test
View file @
523ef2a1
...
...
@@ -14,14 +14,14 @@ create view v2 as select a from t2;
flush
status
;
select
*
from
v2
;
--
disable_ps_protocol
show
status
like
'%Created_tmp%'
;
show
status
like
'%Created_tmp
_tables
%'
;
--
enable_ps_protocol
explain
select
*
from
v2
;
select
*
from
(
select
*
from
t2
)
T1
;
--
disable_ps_protocol
show
status
like
'%Created_tmp%'
;
show
status
like
'%Created_tmp
_tables
%'
;
--
enable_ps_protocol
explain
select
*
from
(
select
*
from
t2
)
T1
;
...
...
@@ -44,7 +44,7 @@ flush status;
CREATE
TABLE
t3
SELECT
*
FROM
t1
WHERE
a
IN
(
SELECT
*
FROM
t2
GROUP
BY
a
HAVING
a
>
1
);
--
echo
# Performance schema should be the same as "Created_tmp_tables" variable below
select
sum
(
created_tmp_tables
)
from
performance_schema
.
events_statements_history_long
;
show
status
like
'%Created_tmp%'
;
show
status
like
'%Created_tmp
_tables
%'
;
drop
table
t3
;
set
@@
optimizer_switch
=
"firstmatch=off"
;
...
...
@@ -54,7 +54,7 @@ flush status;
CREATE
TABLE
t3
SELECT
*
FROM
t1
WHERE
a
IN
(
SELECT
*
FROM
t2
GROUP
BY
a
);
--
echo
# Performance schema should be the same as "Created_tmp_tables" variable below
select
sum
(
created_tmp_tables
)
from
performance_schema
.
events_statements_history_long
;
show
status
like
'%Created_tmp%'
;
show
status
like
'%Created_tmp
_tables
%'
;
set
@@
optimizer_switch
=
default
;
drop
table
t1
,
t2
,
t3
;
...
...
@@ -63,4 +63,4 @@ truncate table performance_schema.events_statements_history_long;
flush
status
;
--
echo
# Performance schema should be the same as "Created_tmp_tables" variable below
select
sum
(
created_tmp_tables
)
from
performance_schema
.
events_statements_history_long
;
show
status
like
'%Created_tmp%'
;
show
status
like
'%Created_tmp
_tables
%'
;
sql/lex_ident_cli.h
0 → 100644
View file @
523ef2a1
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
Copyright (c) 2010, 2024, MariaDB Corporation.
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 */
#ifndef LEX_IDENT_CLI
#define LEX_IDENT_CLI
#include "my_global.h"
#include "m_ctype.h"
/**
A string with metadata. Usually points to a string in the client
character set, but unlike Lex_ident_cli_st (see below) it does not
necessarily point to a query fragment. It can also point to memory
of other kinds (e.g. an additional THD allocated memory buffer
not overlapping with the current query text).
We'll add more flags here eventually, to know if the string has, e.g.:
- multi-byte characters
- bad byte sequences
- backslash escapes: 'a\nb'
and reuse the original query fragments instead of making the string
copy too early, in Lex_input_stream::get_text().
This will allow to avoid unnecessary copying, as well as
create more optimal Item types in sql_yacc.yy
*/
struct
Lex_string_with_metadata_st
:
public
LEX_CSTRING
{
private:
bool
m_is_8bit
;
// True if the string has 8bit characters
char
m_quote
;
// Quote character, or 0 if not quoted
public:
void
set_8bit
(
bool
is_8bit
)
{
m_is_8bit
=
is_8bit
;
}
void
set_metadata
(
bool
is_8bit
,
char
quote
)
{
m_is_8bit
=
is_8bit
;
m_quote
=
quote
;
}
void
set
(
const
char
*
s
,
size_t
len
,
bool
is_8bit
,
char
quote
)
{
str
=
s
;
length
=
len
;
set_metadata
(
is_8bit
,
quote
);
}
void
set
(
const
LEX_CSTRING
*
s
,
bool
is_8bit
,
char
quote
)
{
((
LEX_CSTRING
&
)
*
this
)
=
*
s
;
set_metadata
(
is_8bit
,
quote
);
}
bool
is_8bit
()
const
{
return
m_is_8bit
;
}
bool
is_quoted
()
const
{
return
m_quote
!=
'\0'
;
}
char
quote
()
const
{
return
m_quote
;
}
// Get string repertoire by the 8-bit flag and the character set
my_repertoire_t
repertoire
(
CHARSET_INFO
*
cs
)
const
{
return
!
m_is_8bit
&&
my_charset_is_ascii_based
(
cs
)
?
MY_REPERTOIRE_ASCII
:
MY_REPERTOIRE_UNICODE30
;
}
// Get string repertoire by the 8-bit flag, for ASCII-based character sets
my_repertoire_t
repertoire
()
const
{
return
!
m_is_8bit
?
MY_REPERTOIRE_ASCII
:
MY_REPERTOIRE_UNICODE30
;
}
};
/*
Used to store identifiers in the client character set.
Points to a query fragment.
*/
struct
Lex_ident_cli_st
:
public
Lex_string_with_metadata_st
{
public:
void
set_keyword
(
const
char
*
s
,
size_t
len
)
{
set
(
s
,
len
,
false
,
'\0'
);
}
void
set_ident
(
const
char
*
s
,
size_t
len
,
bool
is_8bit
)
{
set
(
s
,
len
,
is_8bit
,
'\0'
);
}
void
set_ident_quoted
(
const
char
*
s
,
size_t
len
,
bool
is_8bit
,
char
quote
)
{
set
(
s
,
len
,
is_8bit
,
quote
);
}
void
set_unquoted
(
const
LEX_CSTRING
*
s
,
bool
is_8bit
)
{
set
(
s
,
is_8bit
,
'\0'
);
}
const
char
*
pos
()
const
{
return
str
-
is_quoted
();
}
const
char
*
end
()
const
{
return
str
+
length
+
is_quoted
();
}
};
class
Lex_ident_cli
:
public
Lex_ident_cli_st
{
public:
Lex_ident_cli
(
const
LEX_CSTRING
*
s
,
bool
is_8bit
)
{
set_unquoted
(
s
,
is_8bit
);
}
Lex_ident_cli
(
const
char
*
s
,
size_t
len
)
{
set_ident
(
s
,
len
,
false
);
}
};
#endif // LEX_IDENT_CLI
sql/lex_ident_sys.h
0 → 100644
View file @
523ef2a1
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
Copyright (c) 2010, 2024, MariaDB Corporation.
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 */
#ifndef LEX_IDENT_SYS
#define LEX_IDENT_SYS
#include "lex_ident_cli.h"
#include "sql_alloc.h"
extern
"C"
MYSQL_PLUGIN_IMPORT
CHARSET_INFO
*
system_charset_info
;
struct
Lex_ident_sys_st
:
public
LEX_CSTRING
,
Sql_alloc
{
public:
bool
copy_ident_cli
(
const
THD
*
thd
,
const
Lex_ident_cli_st
*
str
);
bool
copy_keyword
(
const
THD
*
thd
,
const
Lex_ident_cli_st
*
str
);
bool
copy_sys
(
const
THD
*
thd
,
const
LEX_CSTRING
*
str
);
bool
convert
(
const
THD
*
thd
,
const
LEX_CSTRING
*
str
,
CHARSET_INFO
*
cs
);
bool
copy_or_convert
(
const
THD
*
thd
,
const
Lex_ident_cli_st
*
str
,
CHARSET_INFO
*
cs
);
bool
is_null
()
const
{
return
str
==
NULL
;
}
bool
to_size_number
(
ulonglong
*
to
)
const
;
void
set_valid_utf8
(
const
LEX_CSTRING
*
name
)
{
DBUG_ASSERT
(
Well_formed_prefix
(
system_charset_info
,
name
->
str
,
name
->
length
).
length
()
==
name
->
length
);
str
=
name
->
str
;
length
=
name
->
length
;
}
};
class
Lex_ident_sys
:
public
Lex_ident_sys_st
{
public:
Lex_ident_sys
(
const
THD
*
thd
,
const
Lex_ident_cli_st
*
str
)
{
if
(
copy_ident_cli
(
thd
,
str
))
*
this
=
Lex_ident_sys
();
}
Lex_ident_sys
()
{
((
LEX_CSTRING
&
)
*
this
)
=
{
nullptr
,
0
};
}
Lex_ident_sys
(
const
char
*
name
,
size_t
length
)
{
LEX_CSTRING
tmp
=
{
name
,
length
};
set_valid_utf8
(
&
tmp
);
}
Lex_ident_sys
(
const
THD
*
thd
,
const
LEX_CSTRING
*
str
)
{
set_valid_utf8
(
str
);
}
Lex_ident_sys
&
operator
=
(
const
Lex_ident_sys_st
&
name
)
{
Lex_ident_sys_st
::
operator
=
(
name
);
return
*
this
;
}
};
#endif // LEX_IDENT_SYS
sql/sql_lex.h
View file @
523ef2a1
...
...
@@ -21,6 +21,7 @@
#ifndef SQL_LEX_INCLUDED
#define SQL_LEX_INCLUDED
#include "lex_ident_sys.h"
#include "violite.h"
/* SSL_type */
#include "sql_trigger.h"
#include "thr_lock.h"
/* thr_lock_type, TL_UNLOCK */
...
...
@@ -47,153 +48,6 @@ typedef Bitmap<SELECT_NESTING_MAP_SIZE> nesting_map;
/* YACC and LEX Definitions */
/**
A string with metadata. Usually points to a string in the client
character set, but unlike Lex_ident_cli_st (see below) it does not
necessarily point to a query fragment. It can also point to memory
of other kinds (e.g. an additional THD allocated memory buffer
not overlapping with the current query text).
We'll add more flags here eventually, to know if the string has, e.g.:
- multi-byte characters
- bad byte sequences
- backslash escapes: 'a\nb'
and reuse the original query fragments instead of making the string
copy too early, in Lex_input_stream::get_text().
This will allow to avoid unnecessary copying, as well as
create more optimal Item types in sql_yacc.yy
*/
struct
Lex_string_with_metadata_st
:
public
LEX_CSTRING
{
private:
bool
m_is_8bit
;
// True if the string has 8bit characters
char
m_quote
;
// Quote character, or 0 if not quoted
public:
void
set_8bit
(
bool
is_8bit
)
{
m_is_8bit
=
is_8bit
;
}
void
set_metadata
(
bool
is_8bit
,
char
quote
)
{
m_is_8bit
=
is_8bit
;
m_quote
=
quote
;
}
void
set
(
const
char
*
s
,
size_t
len
,
bool
is_8bit
,
char
quote
)
{
str
=
s
;
length
=
len
;
set_metadata
(
is_8bit
,
quote
);
}
void
set
(
const
LEX_CSTRING
*
s
,
bool
is_8bit
,
char
quote
)
{
((
LEX_CSTRING
&
)
*
this
)
=
*
s
;
set_metadata
(
is_8bit
,
quote
);
}
bool
is_8bit
()
const
{
return
m_is_8bit
;
}
bool
is_quoted
()
const
{
return
m_quote
!=
'\0'
;
}
char
quote
()
const
{
return
m_quote
;
}
// Get string repertoire by the 8-bit flag and the character set
my_repertoire_t
repertoire
(
CHARSET_INFO
*
cs
)
const
{
return
!
m_is_8bit
&&
my_charset_is_ascii_based
(
cs
)
?
MY_REPERTOIRE_ASCII
:
MY_REPERTOIRE_UNICODE30
;
}
// Get string repertoire by the 8-bit flag, for ASCII-based character sets
my_repertoire_t
repertoire
()
const
{
return
!
m_is_8bit
?
MY_REPERTOIRE_ASCII
:
MY_REPERTOIRE_UNICODE30
;
}
};
/*
Used to store identifiers in the client character set.
Points to a query fragment.
*/
struct
Lex_ident_cli_st
:
public
Lex_string_with_metadata_st
{
public:
void
set_keyword
(
const
char
*
s
,
size_t
len
)
{
set
(
s
,
len
,
false
,
'\0'
);
}
void
set_ident
(
const
char
*
s
,
size_t
len
,
bool
is_8bit
)
{
set
(
s
,
len
,
is_8bit
,
'\0'
);
}
void
set_ident_quoted
(
const
char
*
s
,
size_t
len
,
bool
is_8bit
,
char
quote
)
{
set
(
s
,
len
,
is_8bit
,
quote
);
}
void
set_unquoted
(
const
LEX_CSTRING
*
s
,
bool
is_8bit
)
{
set
(
s
,
is_8bit
,
'\0'
);
}
const
char
*
pos
()
const
{
return
str
-
is_quoted
();
}
const
char
*
end
()
const
{
return
str
+
length
+
is_quoted
();
}
};
class
Lex_ident_cli
:
public
Lex_ident_cli_st
{
public:
Lex_ident_cli
(
const
LEX_CSTRING
*
s
,
bool
is_8bit
)
{
set_unquoted
(
s
,
is_8bit
);
}
Lex_ident_cli
(
const
char
*
s
,
size_t
len
)
{
set_ident
(
s
,
len
,
false
);
}
};
struct
Lex_ident_sys_st
:
public
LEX_CSTRING
,
Sql_alloc
{
public:
bool
copy_ident_cli
(
const
THD
*
thd
,
const
Lex_ident_cli_st
*
str
);
bool
copy_keyword
(
const
THD
*
thd
,
const
Lex_ident_cli_st
*
str
);
bool
copy_sys
(
const
THD
*
thd
,
const
LEX_CSTRING
*
str
);
bool
convert
(
const
THD
*
thd
,
const
LEX_CSTRING
*
str
,
CHARSET_INFO
*
cs
);
bool
copy_or_convert
(
const
THD
*
thd
,
const
Lex_ident_cli_st
*
str
,
CHARSET_INFO
*
cs
);
bool
is_null
()
const
{
return
str
==
NULL
;
}
bool
to_size_number
(
ulonglong
*
to
)
const
;
void
set_valid_utf8
(
const
LEX_CSTRING
*
name
)
{
DBUG_ASSERT
(
Well_formed_prefix
(
system_charset_info
,
name
->
str
,
name
->
length
).
length
()
==
name
->
length
);
str
=
name
->
str
;
length
=
name
->
length
;
}
};
class
Lex_ident_sys
:
public
Lex_ident_sys_st
{
public:
Lex_ident_sys
(
const
THD
*
thd
,
const
Lex_ident_cli_st
*
str
)
{
if
(
copy_ident_cli
(
thd
,
str
))
((
LEX_CSTRING
&
)
*
this
)
=
null_clex_str
;
}
Lex_ident_sys
()
{
((
LEX_CSTRING
&
)
*
this
)
=
null_clex_str
;
}
Lex_ident_sys
(
const
char
*
name
,
size_t
length
)
{
LEX_CSTRING
tmp
=
{
name
,
length
};
set_valid_utf8
(
&
tmp
);
}
Lex_ident_sys
(
const
THD
*
thd
,
const
LEX_CSTRING
*
str
)
{
set_valid_utf8
(
str
);
}
Lex_ident_sys
&
operator
=
(
const
Lex_ident_sys_st
&
name
)
{
Lex_ident_sys_st
::
operator
=
(
name
);
return
*
this
;
}
};
struct
Lex_column_list_privilege_st
{
List
<
Lex_ident_sys
>
*
m_columns
;
...
...
sql/sql_string.h
View file @
523ef2a1
...
...
@@ -55,48 +55,6 @@ inline uint32 copy_and_convert(char *to, size_t to_length, CHARSET_INFO *to_cs,
}
class
String_copy_status
:
protected
MY_STRCOPY_STATUS
{
public:
const
char
*
source_end_pos
()
const
{
return
m_source_end_pos
;
}
const
char
*
well_formed_error_pos
()
const
{
return
m_well_formed_error_pos
;
}
};
class
Well_formed_prefix_status
:
public
String_copy_status
{
public:
Well_formed_prefix_status
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
const
char
*
end
,
size_t
nchars
)
{
cs
->
well_formed_char_length
(
str
,
end
,
nchars
,
this
);
}
};
class
Well_formed_prefix
:
public
Well_formed_prefix_status
{
const
char
*
m_str
;
// The beginning of the string
public:
Well_formed_prefix
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
const
char
*
end
,
size_t
nchars
)
:
Well_formed_prefix_status
(
cs
,
str
,
end
,
nchars
),
m_str
(
str
)
{
}
Well_formed_prefix
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
size_t
length
,
size_t
nchars
)
:
Well_formed_prefix_status
(
cs
,
str
,
str
+
length
,
nchars
),
m_str
(
str
)
{
}
Well_formed_prefix
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
size_t
length
)
:
Well_formed_prefix_status
(
cs
,
str
,
str
+
length
,
length
),
m_str
(
str
)
{
}
Well_formed_prefix
(
CHARSET_INFO
*
cs
,
LEX_CSTRING
str
,
size_t
nchars
)
:
Well_formed_prefix_status
(
cs
,
str
.
str
,
str
.
str
+
str
.
length
,
nchars
),
m_str
(
str
.
str
)
{
}
size_t
length
()
const
{
return
m_source_end_pos
-
m_str
;
}
};
class
String_copier
:
public
String_copy_status
,
protected
MY_STRCONV_STATUS
{
...
...
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