Commit 42af46ca authored by paul@teton.kitebird.com's avatar paul@teton.kitebird.com

manual merge

parents f2d8e159 d8c9b903
......@@ -12423,6 +12423,12 @@ mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
@end example
On character type columns, sorting@-like all other comparison
operations@-is normally performed in a case-insensitive fashion.
This means that the order will be undefined for columns that are identical
except for their case. You can force a case-sensitive sort by using the
BINARY cast: @code{ORDER BY BINARY(field)}.
To sort in reverse order, add the @code{DESC} (descending) keyword to the
name of the column you are sorting by:
......@@ -29339,6 +29345,15 @@ interpreted as the year @code{'2010-11-12'}. The value @code{'10:45:15'}
will be converted to @code{'0000-00-00'} because @code{'45'} is not a legal
month.
@item
The MySQL server only performs basic checking on the validity of a date:
days @code{00-31}, months @code{00-12}, years @code{1000-9999}.
Any date not within this range will revert to @code{0000-00-00}.
Please note that this still allows you to store invalid dates such as
@code{2002-04-31}. It allows web applications to store data from a form
without further checking. To ensure a date is valid, perform a check in
your application.
@item
Year values specified as two digits are ambiguous, because the century is
unknown. MySQL interprets 2-digit year values using the following
......@@ -49098,7 +49113,15 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@itemize @bullet
@item
Query cache disabled in @code{mysqldump}.
Fixed bug in phrase operator @code{"..."} in boolean fulltext search.
@item
Fixed bug that caused duplicated rows when using truncation operator
@code{*} in boolean fulltext search.
@item
Fixed bug in boolean fulltext search, that caused a crash when an identical
@code{MATCH} expression that did not use an index appeared twice.
@item
Query cache disabled in mysqldump.
@item
Fixed problem on Windows 98 that made sending of results very slow.
@item
......@@ -16,7 +16,8 @@
C_MODE_START
enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_LONG, GET_LL, GET_STR };
enum get_opt_var_type { GET_NO_ARG, GET_BOOL, GET_INT, GET_UINT, GET_LONG,
GET_ULONG, GET_LL, GET_ULL, GET_STR };
enum get_opt_arg_type { NO_ARG, OPT_ARG, REQUIRED_ARG };
struct my_option
......
......@@ -77,7 +77,7 @@ typedef struct st_ftb_word {
my_off_t docid[2]; /* for index search and for scan */
uint ndepth;
int len;
/* ... there can be docid cache added here. SerG */
/* ... docid cache can be added here. SerG */
byte word[1];
} FTB_WORD;
......@@ -90,6 +90,7 @@ typedef struct st_ft_info {
uint with_scan;
FTB_EXPR *root;
QUEUE queue;
TREE no_dupes;
FTB_WORD **list;
MEM_ROOT mem_root;
} FTB;
......@@ -165,6 +166,7 @@ void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
if ((ftbe->quot=param.quot)) ftb->with_scan|=2;
if (param.yesno > 0) up->ythresh++;
_ftb_parse_query(ftb, start, end, ftbe, depth+1);
param.quot=0;
break;
case 3: /* right bracket */
if (up->quot) up->qend=param.quot;
......@@ -174,6 +176,11 @@ void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
return;
}
static int _ftb_no_dupes_cmp(void* not_used, const void *a,const void *b)
{
return CMP_NUM((*((my_off_t*)a)), (*((my_off_t*)b)));
}
void _ftb_init_index_search(FT_INFO *ftb)
{
int i, r;
......@@ -193,8 +200,8 @@ void _ftb_init_index_search(FT_INFO *ftb)
{
ftbw=(FTB_WORD *)(ftb->queue.root[i]);
if (ftbw->flags&FTB_FLAG_TRUNC &&
(ftbw->up->ythresh > test(ftbw->flags&FTB_FLAG_YES)))
if (ftbw->flags&FTB_FLAG_TRUNC) /* special treatment :(( */
if (ftbw->up->ythresh > test(ftbw->flags&FTB_FLAG_YES))
{
/* no need to search for this prefix in the index -
* it cannot ADD new matches, and to REMOVE half-matched
......@@ -203,6 +210,21 @@ void _ftb_init_index_search(FT_INFO *ftb)
ftbw->up->yweaks++;
continue;
}
else
{
/* We have to index-search for this prefix.
* It may cause duplicates, as in the index (sorted by <word,docid>)
* <aaaa,row1>
* <aabb,row2>
* <aacc,row1>
* Searching for "aa*" will find row1 twice...
*/
if (!is_tree_inited(& ftb->no_dupes))
{
init_tree(& ftb->no_dupes,0,0,sizeof(my_off_t),
_ftb_no_dupes_cmp,0,0,0);
}
}
r=_mi_search(info, keyinfo, (uchar*) ftbw->word, ftbw->len,
SEARCH_FIND | SEARCH_BIGGER, keyroot);
......@@ -250,6 +272,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
default_charset_info :
info->s->keyinfo[keynr].seg->charset);
ftb->with_scan=0;
bzero(& ftb->no_dupes, sizeof(TREE));
init_alloc_root(&ftb->mem_root, 1024, 1024);
......@@ -438,6 +461,11 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record)
ftbe->yesses>=(ftbe->ythresh-ftbe->yweaks) && !ftbe->nos)
{
/* curdoc matched ! */
if (is_tree_inited(& ftb->no_dupes) &&
tree_insert(& ftb->no_dupes, &curdoc, 0)->count >1)
/* but it managed to get past this line once */
continue;
info->lastpos=curdoc;
info->update&= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); /* why is this ? */
......@@ -523,6 +551,10 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
void ft_boolean_close_search(FT_INFO *ftb)
{
if (is_tree_inited(& ftb->no_dupes))
{
delete_tree(& ftb->no_dupes);
}
free_root(& ftb->mem_root, MYF(0));
my_free((gptr)ftb,MYF(0));
}
......
......@@ -134,7 +134,7 @@ byte ft_get_word(byte **start, byte *end, FT_WORD *word, FTB_PARAM *param)
{
if (true_word_char(*doc)) break;
if (*doc == FTB_RQUOT && param->quot) {
param->quot=doc-1;
param->quot=doc;
*start=doc+1;
return 3; /* FTB_RBR */
}
......
......@@ -70,6 +70,16 @@ Full-text search in MySQL implements vector space model 0
select * from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE);
a b
MySQL has now support for full-text search
select * from t1 where MATCH a,b AGAINST ('"text search" "now support"' IN BOOLEAN MODE);
a b
MySQL has now support for full-text search
Full-text search in MySQL implements vector space model
select * from t1 where MATCH a,b AGAINST ('"text search" -"now support"' IN BOOLEAN MODE);
a b
Full-text search in MySQL implements vector space model
select * from t1 where MATCH a,b AGAINST ('"text search" +"now support"' IN BOOLEAN MODE);
a b
MySQL has now support for full-text search
select * from t1 where MATCH a AGAINST ("search" IN BOOLEAN MODE);
a b
Full-text search in MySQL implements vector space model
......@@ -173,4 +183,9 @@ CREATE TABLE t1 (a int(11), b text, FULLTEXT KEY (b)) TYPE=MyISAM;
insert into t1 values (1,"I wonder why the fulltext index doesnt work?");
SELECT * from t1 where MATCH (b) AGAINST ('apples');
a b
insert into t1 values (2,"fullaaa fullzzz");
select * from t1 where match b against ('full*' in boolean mode);
a b
2 fullaaa fullzzz
1 I wonder why the fulltext index doesnt work?
drop table t1;
......@@ -34,6 +34,9 @@ select *, MATCH(a,b) AGAINST("support collections" IN BOOLEAN MODE) as x from t1
select *, MATCH(a,b) AGAINST("collections support" IN BOOLEAN MODE) as x from t1;
select * from t1 where MATCH a,b AGAINST ('"Now sUPPort"' IN BOOLEAN MODE);
select * from t1 where MATCH a,b AGAINST ('"text search" "now support"' IN BOOLEAN MODE);
select * from t1 where MATCH a,b AGAINST ('"text search" -"now support"' IN BOOLEAN MODE);
select * from t1 where MATCH a,b AGAINST ('"text search" +"now support"' IN BOOLEAN MODE);
# boolean w/o index:
......@@ -145,4 +148,8 @@ CREATE TABLE t1 (a int(11), b text, FULLTEXT KEY (b)) TYPE=MyISAM;
insert into t1 values (1,"I wonder why the fulltext index doesnt work?");
SELECT * from t1 where MATCH (b) AGAINST ('apples');
insert into t1 values (2,"fullaaa fullzzz");
select * from t1 where match b against ('full*' in boolean mode);
drop table t1;
......@@ -26,8 +26,11 @@ static int findopt (char *optpat, uint length,
static my_bool compare_strings (register const char *s, register const char *t,
uint length);
static longlong getopt_ll (char *arg, const struct my_option *optp, int *err);
static ulonglong getopt_ull (char *arg, const struct my_option *optp,
int *err);
static void init_variables(const struct my_option *options);
static int setval (const struct my_option *opts, char *argument,
my_bool set_maximum_value);
#define DISABLE_OPTION_COUNT 2
......@@ -66,15 +69,16 @@ int handle_options(int *argc, char ***argv,
char *))
{
uint opt_found, argvpos= 0, length, spec_len, i;
int err= 0;
my_bool end_of_options= 0, must_be_var, set_maximum_value, special_used;
char *progname= *(*argv), **pos, *optend, *prev_found;
const struct my_option *optp;
int error;
LINT_INIT(opt_found);
(*argc)--; /* Skip the program name */
(*argv)++; /* --- || ---- */
init_variables(longopts);
for (pos= *argv; *pos; pos++)
{
char *cur_arg= *pos;
......@@ -337,6 +341,13 @@ int handle_options(int *argc, char ***argv,
/* the other loop will break, because *optend + 1 == 0 */
}
}
if ((error= setval(optp, argument, set_maximum_value)))
{
fprintf(stderr,
"%s: Error while setting value '%s' to '%s'\n",
progname, argument, optp->name);
return error;
}
get_one_option(optp->id, optp, argument);
break;
}
......@@ -351,25 +362,12 @@ int handle_options(int *argc, char ***argv,
(*argc)--; /* option handled (short), decrease argument count */
continue;
}
if (optp->value)
{
gptr *result_pos= (set_maximum_value) ?
optp->u_max_value : optp->value;
if (!result_pos)
if ((error= setval(optp, argument, set_maximum_value)))
{
fprintf(stderr,
"%s: Can't set a value for %s\n", progname, optp->name);
return ERR_NO_PTR_TO_VARIABLE;
}
if (optp->var_type == GET_LONG)
*((long*) result_pos)= (long) getopt_ll(argument, optp, &err);
else if (optp->var_type == GET_LL)
*((longlong*) result_pos)= getopt_ll(argument, optp, &err);
else if (optp->var_type == GET_STR)
*((char**) result_pos)= argument;
if (err)
return ERR_UNKNOWN_SUFFIX;
"%s: Error while setting value '%s' to '%s'\n",
progname, argument, optp->name);
return error;
}
get_one_option(optp->id, optp, argument);
......@@ -381,6 +379,41 @@ int handle_options(int *argc, char ***argv,
return 0;
}
/*
function: setval
Arguments: opts, argument
Will set the option value to given value
*/
static int setval (const struct my_option *opts, char *argument,
my_bool set_maximum_value)
{
int err= 0;
if (opts->value && argument)
{
gptr *result_pos= (set_maximum_value) ?
opts->u_max_value : opts->value;
if (!result_pos)
return ERR_NO_PTR_TO_VARIABLE;
if (opts->var_type == GET_INT || opts->var_type == GET_UINT)
*((int*) result_pos)= (int) getopt_ll(argument, opts, &err);
else if (opts->var_type == GET_LONG || opts->var_type == GET_ULONG)
*((long*) result_pos)= (long) getopt_ll(argument, opts, &err);
else if (opts->var_type == GET_LL)
*((longlong*) result_pos)= getopt_ll(argument, opts, &err);
else if (opts->var_type == GET_ULL)
*((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
else if (opts->var_type == GET_STR)
*((char**) result_pos)= argument;
if (err)
return ERR_UNKNOWN_SUFFIX;
}
return 0;
}
/*
function: findopt
......@@ -436,25 +469,20 @@ static my_bool compare_strings(register const char *s, register const char *t,
return 0;
}
/*
function: getopt_ll
function: eval_num_suffix
Evaluates and returns the value that user gave as an argument
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
and G as GIGA bytes. Some values must be in certain blocks, as
defined in the given my_option struct, this function will check
that those values are honored.
In case of an error, set error value in *err.
Transforms a number with a suffix to real number. Suffix can
be k|K for kilo, m|M for mega or g|G for giga.
*/
static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
static longlong eval_num_suffix (char *argument, int *error, char *option_name)
{
char *endchar;
longlong num;
*err= 0;
num= strtoll(arg, &endchar, 10);
*error= 0;
num= strtoll(argument, &endchar, 10);
if (*endchar == 'k' || *endchar == 'K')
num*= 1024L;
else if (*endchar == 'm' || *endchar == 'M')
......@@ -465,9 +493,29 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
{
fprintf(stderr,
"Unknown suffix '%c' used for variable '%s' (value '%s')\n",
*endchar, optp->name, arg);
*err= 1;
*endchar, option_name, argument);
*error= 1;
return 0;
}
return num;
}
/*
function: getopt_ll
Evaluates and returns the value that user gave as an argument
to a variable. Recognizes (case insensitive) K as KILO, M as MEGA
and G as GIGA bytes. Some values must be in certain blocks, as
defined in the given my_option struct, this function will check
that those values are honored.
In case of an error, set error value in *err.
*/
static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
{
longlong num;
num= eval_num_suffix(arg, err, (char*) optp->name);
if (num < (longlong) optp->min_value)
num= (longlong) optp->min_value;
else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value
......@@ -480,6 +528,29 @@ static longlong getopt_ll (char *arg, const struct my_option *optp, int *err)
1L));
}
/*
function: getopt_ull
This is the same as getopt_ll, but is meant for unsigned long long
values.
*/
static ulonglong getopt_ull (char *arg, const struct my_option *optp, int *err)
{
ulonglong num;
num= eval_num_suffix(arg, err, (char*) optp->name);
if (num < (ulonglong) optp->min_value)
num= (ulonglong) optp->min_value;
else if (num > 0 && (ulonglong) num > (ulonglong) (ulong) optp->max_value
&& optp->max_value) // if max value is not set -> no upper limit
num= (ulonglong) (ulong) optp->max_value;
num= ((num - (ulonglong) optp->sub_size) / (optp->block_size ?
(ulonglong) optp->block_size :
1L));
return (ulonglong) (num * (optp->block_size ? (ulonglong) optp->block_size :
1L));
}
/*
function: init_variables
......@@ -493,12 +564,24 @@ static void init_variables(const struct my_option *options)
{
if (options->value)
{
if (options->var_type == GET_LONG)
if (options->var_type == GET_INT)
*((int*) options->u_max_value)= *((int*) options->value)=
(int) options->def_value;
else if (options->var_type == GET_UINT)
*((uint*) options->u_max_value)= *((uint*) options->value)=
(uint) options->def_value;
else if (options->var_type == GET_LONG)
*((long*) options->u_max_value)= *((long*) options->value)=
(long) options->def_value;
else if (options->var_type == GET_ULONG)
*((ulong*) options->u_max_value)= *((ulong*) options->value)=
(ulong) options->def_value;
else if (options->var_type == GET_LL)
*((longlong*) options->u_max_value)= *((longlong*) options->value)=
options->def_value;
(longlong) options->def_value;
else if (options->var_type == GET_ULL)
*((ulonglong*) options->u_max_value)= *((ulonglong*) options->value)=
(ulonglong) options->def_value;
}
}
}
......@@ -604,6 +687,20 @@ void my_print_variables(const struct my_option *options)
else
printf("(No default value)\n");
}
else if (optp->var_type == GET_INT)
{
if (!optp->def_value && !*((int*) optp->value))
printf("(No default value)\n");
else
printf("%d\n", *((int*) optp->value));
}
else if (optp->var_type == GET_UINT)
{
if (!optp->def_value && !*((uint*) optp->value))
printf("(No default value)\n");
else
printf("%d\n", *((uint*) optp->value));
}
else if (optp->var_type == GET_LONG)
{
if (!optp->def_value && !*((long*) optp->value))
......@@ -611,13 +708,27 @@ void my_print_variables(const struct my_option *options)
else
printf("%lu\n", *((long*) optp->value));
}
else if (optp->var_type == GET_ULONG)
{
if (!optp->def_value && !*((ulong*) optp->value))
printf("(No default value)\n");
else
printf("%lu\n", *((ulong*) optp->value));
}
else if (optp->var_type == GET_LL)
{
if (!optp->def_value && !*((longlong*) optp->value))
printf("(No default value)\n");
else
printf("%s\n", llstr(*((longlong*) optp->value), buff));
}
else if (optp->var_type == GET_ULL)
{
if (!optp->def_value && !*((ulonglong*) optp->value))
printf("(No default value)\n");
else
printf("%s\n", longlong2str(*((ulonglong*) optp->value), buff, 10));
}
}
}
}
......@@ -2039,6 +2039,9 @@ void Item_func_match::init_search(bool no_order)
if (ft_handler)
return;
if (key == NO_SUCH_KEY)
concat=new Item_func_concat_ws (new Item_string(" ",1), fields);
if (master)
{
join_key=master->join_key=join_key|master->join_key;
......@@ -2048,9 +2051,6 @@ void Item_func_match::init_search(bool no_order)
return;
}
if (key == NO_SUCH_KEY)
concat=new Item_func_concat_ws (new Item_string(" ",1), fields);
String *ft_tmp=0;
char tmp1[FT_QUERY_MAXLEN];
String tmp2(tmp1,sizeof(tmp1));
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -479,3 +479,33 @@ If this condition persist, reboot the machine and try again\n");
return ret_value;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
BOOL NTService::IsService(LPCSTR ServiceName)
{
BOOL ret_value=FALSE;
SC_HANDLE service, scm;
if (scm = OpenSCManager(0, 0,SC_MANAGER_ENUMERATE_SERVICE))
{
if ((service = OpenService(scm,ServiceName, SERVICE_ALL_ACCESS )))
{
ret_value=TRUE;
CloseServiceHandle(service);
}
CloseServiceHandle(scm);
}
return ret_value;
}
/* ------------------------------------------------------------------------
-------------------------------------------------------------------------- */
BOOL NTService::got_service_option(char **argv, char *service_option)
{
char *option = argv[1];
while (*option)
if (!strcmp(option++, service_option))
return TRUE;
return FALSE;
}
......@@ -52,6 +52,8 @@ class NTService
LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL);
BOOL SeekStatus(LPCSTR szInternName, int OperationType);
BOOL Remove(LPCSTR szInternName);
BOOL IsService(LPCSTR ServiceName);
BOOL got_service_option(char **argv, char *service_option);
void Stop(void); //to be called from app. to stop service
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment