This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Bug Report


While re-compiling MySQL-3.22.32-1.src.rpm from www.mysql.com into
unedited, straight from a CD-ROM Linux RedHat 6.0 (Custom installed with
quite light amount of stuff, can get you whole list if needed)

Linux polyfoam.sby.abo.fi 2.2.5-15 #1 Mon Apr 19 23:00:46 EDT 1999 i686
unknown

I Got a following message:


RCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -O3 -DDBUG_OFF  -O6
-fomit-frame-pointer 	          -felide-constructors -fno-exceptions
-fno-rtti  -fno-implicit-templates -D_FILE_OFFSET_BITS=64 -c
item_cmpfunc.c
item_cmpfunc.cc: In method `void in_vector::sort()':
item_cmpfunc.cc:919: Internal compiler error.
item_cmpfunc.cc:919: Please submit a full bug report to
`egcs-bugs@egcs.cygnus.com'.
item_cmpfunc.cc:919: See <URL:http://egcs.cygnus.com/faq.html#bugreport>
for details.
make[3]: *** [item_cmpfunc.o] Error 1
make[3]: Leaving directory `/usr/src/redhat/BUILD/mysql-3.22.32/sql'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/usr/src/redhat/BUILD/mysql-3.22.32/sql'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/usr/src/redhat/BUILD/mysql-3.22.32'
make: *** [all-recursive-am] Error 2
Bad exit status from /var/tmp/rpm-tmp.59304 (%build)



Well. I know what else should I tell you (lamer with linux yet... sorry)

Contact if U need some info


-Mikko Ranta
/* Copyright (C) 1979-1996 TcX AB & Monty Program KB & Detron HB

   This software is distributed with NO WARRANTY OF ANY KIND.  No author or
   distributor accepts any responsibility for the consequences of using it, or
   for whether it serves any particular purpose or works at all, unless he or
   she says so in writing.  Refer to the Free Public License (the "License")
   for full details.

   Every copy of this file must include a copy of the License, normally in a
   plain ASCII text file named PUBLIC.	The License grants you the right to
   copy, modify and redistribute this file, but only under certain conditions
   described in the License.  Among other things, the License requires that
   the copyright notice and this notice be preserved on all copies. */

/* This file defines all compare functions */

#ifdef __GNUC__
#pragma implementation				// gcc: Class implementation
#endif

#include "mysql_priv.h"
#include <m_ctype.h>

/*
** Test functions
** These returns 0LL if false and 1LL if true and null if some arg is null
** 'AND' and 'OR' never return null
*/

longlong Item_func_not::val_int()
{
  double val=args[0]->val();
  null_value=args[0]->null_value;
  return !null_value && val == 0 ? 1 : 0;
}

void Item_bool_func2::fix_length_and_dec()
{
  decimals=0; max_length=1;
  // Make a special case of compare with fields to get nicer DATE comparisons

  if (args[0]->type() == FIELD_ITEM)
  {
    Field *field=((Item_field*) args[0])->field;
    if (field->store_for_compare() && args[1]->const_item())
    {
      Item *item=args[1];
      item->save_in_field(field);
      if (!item->null_value)
      {
	args[1]=new Item_int(field->val_int());
#ifdef DELETE_ITEMS
	delete item;
#endif
	cmp_type=INT_RESULT;			// Works for all types.
	return;
      }
    }
  }
  if (args[1]->type() == FIELD_ITEM)
  {
    Field *field=((Item_field*) args[1])->field;
    if (field->store_for_compare() && args[0]->const_item())
    {
      Item *item=args[0];
      item->save_in_field(field);
      if (!item->null_value)
      {
	args[0]=new Item_int(field->val_int());
#ifdef DELETE_ITEMS
	delete item;
#endif
	cmp_type=INT_RESULT;			// Works for all types.
	return;
      }
    }
  }
  cmp_type=item_cmp_type(args[0]->result_type(),args[1]->result_type());
}


int Item_bool_func2::compare()
{
  null_value=0;
  if (cmp_type == STRING_RESULT)
  {
    String *res1,*res2;
    res1=args[0]->str(&tmp_value1);
    res2=args[1]->str(&tmp_value2);
    if (!args[0]->null_value && !args[1]->null_value)
    {
      return binary ? stringcmp(res1,res2) : sortcmp(res1,res2);
    }
  }
  else if (cmp_type == REAL_RESULT)
  {
    double val1=args[0]->val();
    double val2=args[1]->val();

    if (!args[0]->null_value && !args[1]->null_value)
    {
      if (val1 < val2)	return -1;
      if (val1 == val2) return 0;
      return 1;
    }
  }
  else
  {
    longlong val1=args[0]->val_int();
    longlong val2=args[1]->val_int();

    if (!args[0]->null_value && !args[1]->null_value)
    {
      if (val1 < val2)	return -1;
      if (val1 == val2) return 0;
      return 1;
    }
  }
  null_value=1;
  return 0;
}


longlong Item_func_eq::val_int()
{
  int val=compare();
#ifdef mSQL_COMPLIANT
  // mSQL returns true if one compares NULL_value=NULL constant
  if (null_value)
  {
    if (args[0]->type() == NULL_ITEM ||
	args[1]->type() == NULL_ITEM)
    {						// Compare with NULL const
      if (args[0]->null_value && args[1]->null_value)
      {
	null_value=0;
	return 1;
      }
    }
    return 0;
  }
#endif
  return val == 0 && !null_value ? 1 : 0;
}


longlong Item_func_ne::val_int()
{
  int val=compare();
#ifdef mSQL_COMPLIANT
  // mSQL returns true if one compares NOT NULL_value <> NULL constant
  if (null_value)
  {
    if (args[0]->type() == NULL_ITEM ||
	args[1]->type() == NULL_ITEM)
    {						// Compare with NULL const
      null_value=0;
      return (args[0]->null_value && args[1]->null_value) ? 0 : 1;
    }
    return 0;
  }
#endif
  return val != 0 && !null_value ? 1 : 0;
}


longlong Item_func_ge::val_int()
{
  int val=compare();
  return val >= 0 && !null_value ? 1 : 0;
}


longlong Item_func_gt::val_int()
{
  int val=compare();
  return val > 0 ? 1 : 0;
}

longlong Item_func_le::val_int()
{
  int val=compare();
  return val <= 0 && !null_value ? 1 : 0;
}


longlong Item_func_lt::val_int()
{
  int val=compare();
  return val < 0 ? 1 : 0;
}


longlong Item_func_strcmp::val_int()
{
  String *a=args[0]->str(&tmp_value1);
  String *b=args[1]->str(&tmp_value2);
  if (!a || !b)
  {
    null_value=1;
    return 0;
  }
  int val=stringcmp(a,b);
  null_value=0;
  return !val ? 0 : (val < 0 ? (longlong) -1 : (longlong) 1);
}


void Item_func_interval::fix_length_and_dec()
{
  bool nums=1;
  for (uint i=0 ; i < arg_count ; i++)
  {
    if (args[i]->type() != Item::INT_ITEM &&
	args[i]->type() != Item::REAL_ITEM)
    {
      nums=0;
      break;
    }
  }
  if (nums && arg_count >= 8)
  {
    intervals=(double*) sql_alloc(sizeof(double)*arg_count);
    for (uint i=0 ; i < arg_count ; i++)
      intervals[i]=args[i]->val();
  }
  maybe_null=0; max_length=2;
  used_tables_cache|=item->used_tables();
}

/*
  return -1 if null value,
	  0 if lower than lowest
	  1 - arg_count if between args[n] and args[n+1]
	  arg_count+1 if higher than biggest argument
*/

longlong Item_func_interval::val_int()
{
  double value=item->val();
  if (item->null_value)
    return -1;				// -1 if null /* purecov: inspected */
  if (intervals)
  {					// Use binary search to find interval
    uint start,end;
    start=0; end=arg_count-1;
    while (start != end)
    {
      uint mid=(start+end+1)/2;
      if (intervals[mid] <= value)
	start=mid;
      else
	end=mid-1;
    }
    return (value < intervals[start]) ? 0 : start+1;
  }
  if (args[0]->val() > value)
    return 0;
  for (uint i=1 ; i < arg_count ; i++)
  {
    if (args[i]->val() > value)
      return i;
  }
  return (longlong) arg_count;
}


void Item_func_interval::update_used_tables()
{
  Item_func::update_used_tables();
  item->update_used_tables();
  used_tables_cache|=item->used_tables();
}

void Item_func_between::fix_length_and_dec()
{
  max_length=1;
  if (args[0]->binary)
    string_compare=stringcmp;
  else
    string_compare=sortcmp;
}

longlong Item_func_between::val_int()
{						// ANSI BETWEEN
  if (args[0]->result_type() == STRING_RESULT)
  {
    String *value,*a,*b;
    value=args[0]->str(&value0);
    if ((null_value=args[0]->null_value))
      return 0;
    a=args[1]->str(&value1);
    b=args[2]->str(&value2);
    if (!args[1]->null_value && !args[2]->null_value)
      return (string_compare(value,a) >= 0 && string_compare(value,b) <= 0) ?
	1 : 0;
    if (args[1]->null_value && args[2]->null_value)
      null_value=1;
    else if (args[1]->null_value)
    {
      null_value= string_compare(value,b) <= 0; // not null if false range.
    }
    else
    {
      null_value= string_compare(value,a) >= 0; // not null if false range.
    }
  }
  else if (args[0]->result_type() == INT_RESULT)
  {
    longlong value=args[0]->val_int(),a,b;
    if ((null_value=args[0]->null_value))
      return 0; /* purecov: inspected */
    a=args[1]->val_int();
    b=args[2]->val_int();
    if (!args[1]->null_value && !args[2]->null_value)
      return (value >= a && value <= b) ? 1 : 0;
    if (args[1]->null_value && args[2]->null_value)
      null_value=1;
    else if (args[1]->null_value)
    {
      null_value= value <= b;			// not null if false range.
    }
    else
    {
      null_value= value >= a;
    }
  }
  else
  {
    double value=args[0]->val(),a,b;
    if ((null_value=args[0]->null_value))
      return 0; /* purecov: inspected */
    a=args[1]->val();
    b=args[2]->val();
    if (!args[1]->null_value && !args[2]->null_value)
      return (value >= a && value <= b) ? 1 : 0;
    if (args[1]->null_value && args[2]->null_value)
      null_value=1;
    else if (args[1]->null_value)
    {
      null_value= value <= b;			// not null if false range.
    }
    else
    {
      null_value= value >= a;
    }
  }
  return 0;
}

void
Item_func_ifnull::fix_length_and_dec()
{
  maybe_null=args[1]->maybe_null;
  max_length=max(args[0]->max_length,args[1]->max_length);
  decimals=max(args[0]->decimals,args[1]->decimals);
  cached_result_type=args[0]->result_type();
}

double
Item_func_ifnull::val()
{
  double value=args[0]->val();
  if (!args[0]->null_value)
  {
    null_value=0;
    return value;
  }
  value=args[1]->val();
  if ((null_value=args[1]->null_value))
    return 0.0;
  return value;
}

longlong
Item_func_ifnull::val_int()
{
  longlong value=args[0]->val_int();
  if (!args[0]->null_value)
  {
    null_value=0;
    return value;
  }
  value=args[1]->val_int();
  if ((null_value=args[1]->null_value))
    return 0;
  return value;
}

String *
Item_func_ifnull::str(String *str)
{
  String *res  =args[0]->str(str);
  if (!args[0]->null_value)
  {
    null_value=0;
    return res;
  }
  res=args[1]->str(str);
  if ((null_value=args[1]->null_value))
    return 0;
  return res;
}

void
Item_func_if::fix_length_and_dec()
{
  maybe_null=args[1]->maybe_null || args[2]->maybe_null;
  max_length=max(args[1]->max_length,args[2]->max_length);
  decimals=max(args[0]->decimals,args[1]->decimals);
  cached_result_type = args[1]->result_type();
}


double
Item_func_if::val()
{
  Item *arg= args[0]->val_int() ? args[1] : args[2];
  double value=arg->val();
  null_value=arg->null_value;
  return value;
}

longlong
Item_func_if::val_int()
{
  Item *arg= args[0]->val_int() ? args[1] : args[2];
  longlong value=arg->val_int();
  null_value=arg->null_value;
  return value;
}

String *
Item_func_if::str(String *str)
{
  Item *arg= args[0]->val_int() ? args[1] : args[2];
  String *res=arg->str(str);
  null_value=arg->null_value;
  return res;
}

/****************************************************************************
** classes and function for the IN operator
****************************************************************************/

static int cmp_longlong(longlong *a,longlong *b)
{
  return *a < *b ? -1 : *a == *b ? 0 : 1;
}

static int cmp_double(double *a,double *b)
{
  return *a < *b ? -1 : *a == *b ? 0 : 1;
}

int in_vector::find(Item *item)
{
  byte *result=get_value(item);
  if (!result || !used_count)
    return 0;				// Null value

  uint start,end;
  start=0; end=used_count-1;
  while (start != end)
  {
    uint mid=(start+end+1)/2;
    int res;
    if ((res=(*compare)(base+mid*size,result)) == 0)
      return 1;
    if (res < 0)
      start=mid;
    else
      end=mid-1;
  }
  return (int) ((*compare)(base+start*size,result) == 0);
}


in_string::in_string(uint elements,qsort_cmp cmp_func)
  :in_vector(elements,sizeof(String),cmp_func),tmp(buff,sizeof(buff))
{}

in_string::~in_string()
{
  for (uint i=0 ; i < count ; i++)
    ((String*) base)[i].free();
}

void in_string::set(uint pos,Item *item)
{
  String *str=((String*) base)+pos;
  String *res=item->str(str);
  if (res && res != str)
    *str= *res;
}

byte *in_string::get_value(Item *item)
{
  return (byte*) item->str(&tmp);
}


in_longlong::in_longlong(uint elements)
  :in_vector(elements,sizeof(longlong),(qsort_cmp) cmp_longlong)
{}

void in_longlong::set(uint pos,Item *item)
{
  ((longlong*) base)[pos]=item->val_int();
}

byte *in_longlong::get_value(Item *item)
{
  tmp=item->val_int();
  if (item->null_value)
    return 0; /* purecov: inspected */
  return (byte*) &tmp;
}


in_double::in_double(uint elements)
  :in_vector(elements,sizeof(double),(qsort_cmp) cmp_double)
{}

void in_double::set(uint pos,Item *item)
{
  ((double*) base)[pos]=item->val();
}

byte *in_double::get_value(Item *item)
{
  tmp=item->val();
  if (item->null_value)
    return 0; /* purecov: inspected */
  return (byte*) &tmp;
}


void Item_func_in::fix_length_and_dec()
{
  if (const_item())
  {
    switch (item->result_type()) {
    case STRING_RESULT:
      if (item->binary)
	array=new in_string(arg_count,(qsort_cmp) stringcmp); /* purecov: inspected */
      else
	array=new in_string(arg_count,(qsort_cmp) sortcmp);
      break;
    case INT_RESULT:
      array= new in_longlong(arg_count);
      break;
    case REAL_RESULT:
      array= new in_double(arg_count);
      break;
    }
    uint j=0;
    for (uint i=0 ; i < arg_count ; i++)
    {
      array->set(j,args[i]);
      if (!args[i]->null_value)			// Skipp NULL values
	j++;
    }
    if ((array->used_count=j))
      array->sort();
  }
  else
  {
    switch (item->result_type()) {
    case STRING_RESULT:
      if (item->binary)
	in_item= new cmp_item_binary_string;
      else
	in_item= new cmp_item_sort_string;
      break;
    case INT_RESULT:
      in_item=	  new cmp_item_int;
      break;
    case REAL_RESULT:
      in_item=	  new cmp_item_real;
      break;
    }
  }
  maybe_null=0; max_length=2;
  used_tables_cache|=item->used_tables();
}


void Item_func_in::print(String *str)
{
  str->append('(');
  item->print(str);
  Item_func::print(str);
  str->append(')');
}


longlong Item_func_in::val_int()
{
  if (array)
    return array->find(item);

  in_item->store_value(item);
  if (item->null_value)
    return 0;
  for (uint i=0 ; i < arg_count ; i++)
  {
    if (!in_item->cmp(args[i]) && !args[i]->null_value)
      return 1;					// Would maybe be nice with i ?
  }
  return 0;
}


void Item_func_in::update_used_tables()
{
  Item_func::update_used_tables();
  item->update_used_tables();
  used_tables_cache|=item->used_tables();
}


longlong Item_func_bit_or::val_int()
{
  ulonglong arg1= (ulonglong) args[0]->val_int();
  if (args[0]->null_value)
  {
    null_value=1; /* purecov: inspected */
    return 0; /* purecov: inspected */
  }
  ulonglong arg2= (ulonglong) args[1]->val_int();
  if (args[1]->null_value)
  {
    null_value=1;
    return 0;
  }
  null_value=0;
  return (longlong) (arg1 | arg2);
}


longlong Item_func_bit_and::val_int()
{
  ulonglong arg1= (ulonglong) args[0]->val_int();
  if (args[0]->null_value)
  {
    null_value=1; /* purecov: inspected */
    return 0; /* purecov: inspected */
  }
  ulonglong arg2= (ulonglong) args[1]->val_int();
  if (args[1]->null_value)
  {
    null_value=1; /* purecov: inspected */
    return 0; /* purecov: inspected */
  }
  null_value=0;
  return (longlong) (arg1 & arg2);
}


bool
Item_cond::fix_fields(THD *thd,TABLE_LIST *tables)
{
  List_iterator<Item> li(list);
  Item *item;
  char buff[sizeof(char*)];			// Max local vars in function
  used_tables_cache=0;

  if (thd && check_stack_overrun(thd,buff))
    return 0;					// Fatal error flag is set!
  while ((item=li++))
  {
    while (item->type() == Item::COND_ITEM &&
	   ((Item_cond*) item)->functype() == functype())
    {						// Identical function
      li.replace(((Item_cond*) item)->list);
      ((Item_cond*) item)->list.empty();
#ifdef DELETE_ITEMS
      delete (Item_cond*) item;
#endif
      item= *li.ref();				// new current item
    }
    if (item->fix_fields(thd,tables))
      return 1; /* purecov: inspected */
    used_tables_cache|=item->used_tables();
    with_sum_func= with_sum_func || item->with_sum_func;
  }
  if (thd)
    thd->cond_count+=list.elements;
  fix_length_and_dec();
  return 0;
}


void Item_cond::split_sum_func(List<Item> &fields)
{
  List_iterator<Item> li(list);
  Item *item;
  while ((item=li++))
  {
    if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
      item->split_sum_func(fields);
    else if (item->used_tables() || item->type() == SUM_FUNC_ITEM)
    {
      fields.push_front(item);
      li.replace(new Item_ref((Item**) fields.head_ref(),0,item->name));
    }
    item->update_used_tables();
    used_tables_cache|=item->used_tables();
  }
}


ulong
Item_cond::used_tables() const
{						// This caches used_tables
  return used_tables_cache;
}

void Item_cond::update_used_tables()
{
  used_tables_cache=0;
  List_iterator<Item> li(list);
  Item *item;
  while ((item=li++))
  {
    item->update_used_tables();
    used_tables_cache|=item->used_tables();
  }
}


void Item_cond::print(String *str)
{
  str->append('(');
  List_iterator<Item> li(list);
  Item *item;
  if ((item=li++))
    item->print(str);
  while ((item=li++))
  {
    str->append(' ');
    str->append(func_name());
    str->append(' ');
    item->print(str);
  }
  str->append(')');
}


longlong Item_cond_and::val_int()
{
  List_iterator<Item> li(list);
  Item *item;
  while ((item=li++))
    if (item->val_int() == 0)
      return 0;
  return 1;
}

longlong Item_cond_or::val_int()
{
  List_iterator<Item> li(list);
  Item *item;
  while ((item=li++))
    if (item->val_int() != 0)
      return 1;
  return 0;
}

longlong Item_func_isnull::val_int()
{
  (void) args[0]->val();
  return (args[0]->null_value) ? 1 : 0;
}

longlong Item_func_isnotnull::val_int()
{
  (void) args[0]->val();
  return !(args[0]->null_value) ? 1 : 0;
}


void Item_func_like::fix_length_and_dec()
{
  decimals=0; max_length=1;
  cmp_type=STRING_RESULT;			// For quick select
}


longlong Item_func_like::val_int()
{
  String *res,*res2;
  res=args[0]->str(&tmp_value1);
  if (args[0]->null_value)
  {
    null_value=1;
    return 0;
  }
  res2=args[1]->str(&tmp_value2);
  if (args[1]->null_value)
  {
    null_value=1;
    return 0;
  }
  null_value=0;
  if (binary)
    return wild_compare(*res,*res2,escape) ? 0 : 1;
  else
    return wild_case_compare(*res,*res2,escape) ? 0 : 1;
}


/* We can optimize a where if first character isn't a wildcard */

Item_func::optimize_type Item_func_like::select_optimize() const
{
  if (args[1]->type() == STRING_ITEM)
  {
    if (((Item_string *) args[1])->str_value[0] != wild_many)
    {
      if ((args[0]->result_type() != STRING_RESULT) ||
	  ((Item_string *) args[1])->str_value[0] != wild_one)
	return OPTIMIZE_OP;
    }
  }
  return OPTIMIZE_NONE;
}

#ifdef USE_REGEX

bool
Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables)
{
  if (args[0]->fix_fields(thd,tables) || args[1]->fix_fields(thd,tables))
    return 1;					/* purecov: inspected */
  with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;;
  max_length=1; decimals=0;
  used_tables_cache=args[0]->used_tables() | args[1]->used_tables();
  if (!regex_compiled && args[1]->const_item())
  {
    char buff[MAX_FIELD_WIDTH];
    String tmp(buff,sizeof(buff));
    String *res=args[1]->str(&tmp);
    if (args[1]->null_value)
    {
      my_error(ER_INVALID_USE_OF_NULL,MYF(0));
      return 1;
    }
    int error;
    if ((error=regcomp(&preg,res->c_ptr(),REG_EXTENDED | REG_NOSUB)))
    {
      char buff[100];
      (void) regerror(error,&preg,buff,sizeof(buff));
      my_printf_error(ER_REGEXP_ERROR,ER(ER_REGEXP_ERROR),MYF(0),buff);
      return 1;
    }
    regex_compiled=regex_is_const=1;
    maybe_null=args[0]->maybe_null;
  }
  else
    maybe_null=1;
  return 0;
}


longlong Item_func_regex::val_int()
{
  char buff[MAX_FIELD_WIDTH];
  String *res, tmp(buff,sizeof(buff));

  res=args[0]->str(&tmp);
  if (args[0]->null_value)
  {
    null_value=1;
    return 0;
  }
  if (!regex_is_const)
  {
    char buff2[MAX_FIELD_WIDTH];
    String *res2, tmp2(buff2,sizeof(buff2));

    res2= args[1]->str(&tmp2);
    if (args[1]->null_value)
    {
      null_value=1;
      return 0;
    }
    if (!regex_compiled || stringcmp(res2,&prev_regexp))
    {
      prev_regexp.copy(*res2);
      if (regex_compiled)
      {
	regfree(&preg);
	regex_compiled=0;
      }
      if (regcomp(&preg,res2->c_ptr(),REG_EXTENDED | REG_NOSUB))
      {
	null_value=1;
	return 0;
      }
      regex_compiled=1;
    }
  }
  null_value=0;
  return regexec(&preg,res->c_ptr(),0,(regmatch_t*) 0,0) ? 0 : 1;
}


Item_func_regex::~Item_func_regex()
{
  if (regex_compiled)
  {
    regfree(&preg);
    regex_compiled=0;
  }
}

#endif /* USE_REGEX */
/* Copyright (C) 1979-1996 TcX AB & Monty Program KB & Detron HB

   This software is distributed with NO WARRANTY OF ANY KIND.  No author or
   distributor accepts any responsibility for the consequences of using it, or
   for whether it serves any particular purpose or works at all, unless he or
   she says so in writing.  Refer to the Free Public License (the "License")
   for full details.

   Every copy of this file must include a copy of the License, normally in a
   plain ASCII text file named PUBLIC.	The License grants you the right to
   copy, modify and redistribute this file, but only under certain conditions
   described in the License.  Among other things, the License requires that
   the copyright notice and this notice be preserved on all copies. */

/* compare and test functions */

#ifdef __GNUC__
#pragma interface			/* gcc class implementation */
#endif

class Item_bool_func :public Item_int_func
{
public:
  Item_bool_func() :Item_int_func() {}
  Item_bool_func(Item *a) :Item_int_func(a) {}
  Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
  void fix_length_and_dec() { decimals=0; max_length=1; }
};

class Item_bool_func2 :public Item_int_func
{						/* Bool with 2 string args */
protected:
  String tmp_value1,tmp_value2;
public:
  Item_result cmp_type;
  Item_bool_func2(Item *a,Item *b) :Item_int_func(a,b) {}
  void fix_length_and_dec();
  int compare();				/* compare arg[0] & arg[1] */
  optimize_type select_optimize() const { return OPTIMIZE_OP; }
  virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; }
  void print(String *str) { Item_func::print_op(str); }
};


class Item_func_not :public Item_bool_func
{
public:
  Item_func_not(Item *a) :Item_bool_func(a) {}
  longlong val_int();
  const char *func_name() const { return "not"; }
};

class Item_func_eq :public Item_bool_func2
{
public:
  Item_func_eq(Item *a,Item *b) :Item_bool_func2(a,b) { };
  longlong val_int();
  enum Functype functype() const { return EQ_FUNC; }
  enum Functype rev_functype() const { return EQ_FUNC; }
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return "="; }
};


class Item_func_ge :public Item_bool_func2
{
public:
  Item_func_ge(Item *a,Item *b) :Item_bool_func2(a,b) { };
  longlong val_int();
  enum Functype functype() const { return GE_FUNC; }
  enum Functype rev_functype() const { return LE_FUNC; }
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return ">="; }
};


class Item_func_gt :public Item_bool_func2
{
public:
  Item_func_gt(Item *a,Item *b) :Item_bool_func2(a,b) { };
  longlong val_int();
  enum Functype functype() const { return GT_FUNC; }
  enum Functype rev_functype() const { return LT_FUNC; }
  cond_result eq_cmp_result() const { return COND_FALSE; }
  const char *func_name() const { return ">"; }
};


class Item_func_le :public Item_bool_func2
{
public:
  Item_func_le(Item *a,Item *b) :Item_bool_func2(a,b) { };
  longlong val_int();
  enum Functype functype() const { return LE_FUNC; }
  enum Functype rev_functype() const { return GE_FUNC; }
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return "<="; }
};


class Item_func_lt :public Item_bool_func2
{
public:
  Item_func_lt(Item *a,Item *b) :Item_bool_func2(a,b) { }
  longlong val_int();
  enum Functype functype() const { return LT_FUNC; }
  enum Functype rev_functype() const { return GT_FUNC; }
  cond_result eq_cmp_result() const { return COND_FALSE; }
  const char *func_name() const { return "<"; }
};


class Item_func_ne :public Item_bool_func2
{
public:
  Item_func_ne(Item *a,Item *b) :Item_bool_func2(a,b) { }
  longlong val_int();
  enum Functype functype() const { return NE_FUNC; }
  cond_result eq_cmp_result() const { return COND_FALSE; }
  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
  const char *func_name() const { return "<>"; }
};


class Item_func_between :public Item_int_func
{
  int (*string_compare)(const String *x,const String *y);
public:
  String value0,value1,value2;
  Item_func_between(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
  longlong val_int();
  optimize_type select_optimize() const { return OPTIMIZE_KEY; }
  enum Functype functype() const   { return BETWEEN; }
  const char *func_name() const { return "between"; }
  void fix_length_and_dec();
};


class Item_func_strcmp :public Item_bool_func2
{
public:
  Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {}
  longlong val_int();
  void fix_length_and_dec() { max_length=2; }
  optimize_type select_optimize() const { return OPTIMIZE_NONE; }
  const char *func_name() const { return "strcmp"; }
};


class Item_func_interval :public Item_int_func
{
  Item *item;
  double *intervals;
public:
  Item_func_interval(Item *a,List<Item> &list)
    :Item_int_func(list),item(a),intervals(0) {}
  longlong val_int();
  bool fix_fields(THD *thd,struct st_table_list *tlist)
  {
    return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
  }
  void fix_length_and_dec();
  ~Item_func_interval() { delete item; }
  const char *func_name() const { return "interval"; }
  void update_used_tables();
};


class Item_func_ifnull :public Item_func
{
  enum Item_result cached_result_type;
public:
  Item_func_ifnull(Item *a,Item *b) :Item_func(a,b) { }
  double val();
  longlong val_int();
  String *str(String *str);
  enum Item_result result_type () const { return cached_result_type; }
  void fix_length_and_dec();
  const char *func_name() const { return "ifnull"; }
};


class Item_func_if :public Item_func
{
  enum Item_result cached_result_type;
public:
  Item_func_if(Item *a,Item *b,Item *c) :Item_func(a,b,c) { }
  double val();
  longlong val_int();
  String *str(String *str);
  enum Item_result result_type () const { return cached_result_type; }
  void fix_length_and_dec();
  const char *func_name() const { return "if"; }
};


/* Functions to handle the optimized IN */

class in_vector :public Sql_alloc
{
 protected:
  char *base;
  uint size;
  qsort_cmp compare;
  uint count;
public:
  uint used_count;
  in_vector(uint elements,uint element_length,qsort_cmp cmp_func)
    :base((char*) sql_calloc(elements*element_length)),
     size(element_length), compare(cmp_func), count(elements),
     used_count(elements) {}
  virtual ~in_vector() {}
  virtual void set(uint pos,Item *item)=0;
  virtual byte *get_value(Item *item)=0;
  void sort()
    {
      qsort(base,used_count,size,compare);
    }
  int find(Item *item);
};


class in_string :public in_vector
{
  char buff[80];
  String tmp;
public:
  in_string(uint elements,qsort_cmp cmp_func);
  ~in_string();
  void set(uint pos,Item *item);
  byte *get_value(Item *item);
};


class in_longlong :public in_vector
{
  longlong tmp;
public:
  in_longlong(uint elements);
  void set(uint pos,Item *item);
  byte *get_value(Item *item);
};


class in_double :public in_vector
{
  double tmp;
public:
  in_double(uint elements);
  void set(uint pos,Item *item);
  byte *get_value(Item *item);
};


/*
** Classes for easy comparing of non const items
*/

class cmp_item :public Sql_alloc
{
public:
  cmp_item() {}
  virtual ~cmp_item() {}
  virtual void store_value(Item *item)=0;
  virtual int cmp(Item *item)=0;
};


class cmp_item_sort_string :public cmp_item {
 protected:
  char value_buff[80];
  String value,*value_res;
public:
  cmp_item_sort_string() :value(value_buff,sizeof(value_buff)) {}
  void store_value(Item *item)
    {
      value_res=item->str(&value);
    }
  int cmp(Item *arg)
    {
      char buff[80];
      String tmp(buff,sizeof(buff)),*res;
      if (!(res=arg->str(&tmp)))
	return 1;				/* Can't be right */
      return sortcmp(value_res,res);
    }
};

class cmp_item_binary_string :public cmp_item_sort_string {
public:
  cmp_item_binary_string() {}
  int cmp(Item *arg)
    {
      char buff[80];
      String tmp(buff,sizeof(buff)),*res;
      if (!(res=arg->str(&tmp)))
	return 1;				/* Can't be right */
      return stringcmp(value_res,res);
    }
};


class cmp_item_int :public cmp_item
{
  longlong value;
public:
  void store_value(Item *item)
    {
      value=item->val_int();
    }
  int cmp(Item *arg)
    {
      return value != arg->val_int();
    }
};


class cmp_item_real :public cmp_item
{
  double value;
public:
  void store_value(Item *item)
    {
      value= item->val();
    }
  int cmp(Item *arg)
    {
      return value != arg->val();
    }
};


class Item_func_in :public Item_int_func
{
  Item *item;
  in_vector *array;
  cmp_item *in_item;
 public:
  Item_func_in(Item *a,List<Item> &list)
    :Item_int_func(list),item(a),array(0),in_item(0) {}
  longlong val_int();
  bool fix_fields(THD *thd,struct st_table_list *tlist)
  {
    return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist));
  }
  void fix_length_and_dec();
  ~Item_func_in() { delete item; delete array; delete in_item; }
  optimize_type select_optimize() const
    { return array ? OPTIMIZE_KEY : OPTIMIZE_NONE; }
  Item *key_item() const { return item; }
  void print(String *str);
  enum Functype functype() const { return IN_FUNC; }
  const char *func_name() const { return " IN "; }
  void update_used_tables();
};



/* Functions used by where clause */

class Item_func_isnull :public Item_bool_func
{
public:
  Item_func_isnull(Item *a) :Item_bool_func(a) {}
  longlong val_int();
  enum Functype functype() const { return ISNULL_FUNC; }
  void fix_length_and_dec()
  {
    decimals=0; max_length=1; maybe_null=0;
    Item_func_isnull::update_used_tables();
  }
  const char *func_name() const { return "isnull"; }
  /* Optimize case of not_null_column IS NULL */
  void update_used_tables()
  {
    if (!args[0]->maybe_null)
      used_tables_cache=0;			/* is always false */
    else
    {
      args[0]->update_used_tables();
      used_tables_cache=args[0]->used_tables();
    }
  }
};

class Item_func_isnotnull :public Item_bool_func
{
public:
  Item_func_isnotnull(Item *a) :Item_bool_func(a) {}
  longlong val_int();
  enum Functype functype() const { return ISNOTNULL_FUNC; }
  void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; }
  const char *func_name() const { return "isnotnull"; }
};

class Item_func_like :public Item_bool_func2
{
  char escape;
public:
  Item_func_like(Item *a,Item *b, char* escape_arg) :Item_bool_func2(a,b),escape(*escape_arg)
  {}
  longlong val_int();
  enum Functype functype() const { return LIKE_FUNC; }
  optimize_type select_optimize() const;
  cond_result eq_cmp_result() const { return COND_TRUE; }
  const char *func_name() const { return "like"; }
  void fix_length_and_dec();
};

#ifdef USE_REGEX

#include <regex.h>

class Item_func_regex :public Item_bool_func
{
  regex_t preg;
  bool regex_compiled;
  bool regex_is_const;
  String prev_regexp;
public:
  Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
    regex_compiled(0),regex_is_const(0) {}
  ~Item_func_regex();
  longlong val_int();
  bool fix_fields(THD *thd,struct st_table_list *tlist);
  const char *func_name() const { return "regex"; }
};

#else

class Item_func_regex :public Item_bool_func
{
public:
  Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b) {}
  longlong val_int() { return 0;}
  const char *func_name() const { return "regex"; }
};

#endif /* USE_REGEX */


typedef class Item COND;

class Item_cond :public Item_bool_func
{
protected:
  List<Item> list;
public:
  Item_cond() : Item_bool_func() {}
  Item_cond(Item *i1,Item *i2) :Item_bool_func()
    { list.push_back(i1); list.push_back(i2); }
  ~Item_cond() { list.delete_elements(); }
  void add(Item *item) { list.push_back(item); }
  bool fix_fields(THD *,struct st_table_list *);

  enum Type type() const { return COND_ITEM; }
  List<Item>* argument_list() { return &list; }
  table_map used_tables() const;
  void update_used_tables();
  void print(String *str);
  void split_sum_func(List<Item> &fields);
  friend int setup_conds(THD *thd,TABLE_LIST *tables,COND *conds);
};


class Item_cond_and :public Item_cond
{
public:
  Item_cond_and() :Item_cond() {}
  Item_cond_and(Item *i1,Item *i2) :Item_cond(i1,i2) {}
  enum Functype functype() const { return COND_AND_FUNC; }
  longlong val_int();
  const char *func_name() const { return "and"; }
};

class Item_cond_or :public Item_cond
{
public:
  Item_cond_or() :Item_cond() {}
  Item_cond_or(Item *i1,Item *i2) :Item_cond(i1,i2) {}
  enum Functype functype() const { return COND_OR_FUNC; }
  longlong val_int();
  const char *func_name() const { return "or"; }
};

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]