~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/item_func.cc

  • Committer: Lee
  • Date: 2008-10-29 02:36:17 UTC
  • mto: (520.4.23 devel) (572.1.2 devel)
  • mto: This revision was merged to the branch mainline in revision 567.
  • Revision ID: lbieber@lbieber-desktop-20081029023617-xiowtwsurvdu6ids
more changes to move functions from item_func.cc/h to the functions directory

Show diffs side-by-side

added added

removed removed

Lines of Context:
149
149
  return copy_or_same(session);
150
150
}
151
151
 
152
 
/* REMOVE ME
153
 
#ifdef EXTRA_DEBUG
154
 
void debug_sync_point(const char* lock_name, uint32_t lock_timeout)
155
 
{
156
 
}
157
 
 
158
 
#endif
159
 
*/
160
 
 
161
 
#define extra_size sizeof(double)
162
 
 
163
 
static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
164
 
                                    bool create_if_not_exists)
165
 
{
166
 
  user_var_entry *entry;
167
 
 
168
 
  if (!(entry = (user_var_entry*) hash_search(hash, (unsigned char*) name.str,
169
 
                                              name.length)) &&
170
 
      create_if_not_exists)
171
 
  {
172
 
    uint32_t size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
173
 
    if (!hash_inited(hash))
174
 
      return 0;
175
 
    if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME | ME_FATALERROR))))
176
 
      return 0;
177
 
    entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
178
 
      extra_size;
179
 
    entry->name.length=name.length;
180
 
    entry->value=0;
181
 
    entry->length=0;
182
 
    entry->update_query_id=0;
183
 
    entry->collation.set(NULL, DERIVATION_IMPLICIT, 0);
184
 
    entry->unsigned_flag= 0;
185
 
    /*
186
 
      If we are here, we were called from a SET or a query which sets a
187
 
      variable. Imagine it is this:
188
 
      INSERT INTO t SELECT @a:=10, @a:=@a+1.
189
 
      Then when we have a Item_func_get_user_var (because of the @a+1) so we
190
 
      think we have to write the value of @a to the binlog. But before that,
191
 
      we have a Item_func_set_user_var to create @a (@a:=10), in this we mark
192
 
      the variable as "already logged" (line below) so that it won't be logged
193
 
      by Item_func_get_user_var (because that's not necessary).
194
 
    */
195
 
    entry->used_query_id=current_session->query_id;
196
 
    entry->type=STRING_RESULT;
197
 
    memcpy(entry->name.str, name.str, name.length+1);
198
 
    if (my_hash_insert(hash,(unsigned char*) entry))
199
 
    {
200
 
      free((char*) entry);
201
 
      return 0;
202
 
    }
203
 
  }
204
 
  return entry;
205
 
}
206
 
 
207
152
/*
208
153
  When a user variable is updated (in a SET command or a query like
209
154
  SELECT @a:= ).
316
261
    true    failure
317
262
*/
318
263
 
 
264
#define extra_size sizeof(double)
 
265
 
319
266
static bool
320
267
update_hash(user_var_entry *entry, bool set_null, void *ptr, uint32_t length,
321
268
            Item_result type, const CHARSET_INFO * const cs, Derivation dv,
852
799
}
853
800
 
854
801
 
855
 
String *
856
 
Item_func_get_user_var::val_str(String *str)
857
 
{
858
 
  assert(fixed == 1);
859
 
  if (!var_entry)
860
 
    return((String*) 0);                        // No such variable
861
 
  return(var_entry->val_str(&null_value, str, decimals));
862
 
}
863
 
 
864
 
 
865
 
double Item_func_get_user_var::val_real()
866
 
{
867
 
  assert(fixed == 1);
868
 
  if (!var_entry)
869
 
    return 0.0;                                 // No such variable
870
 
  return (var_entry->val_real(&null_value));
871
 
}
872
 
 
873
 
 
874
 
my_decimal *Item_func_get_user_var::val_decimal(my_decimal *dec)
875
 
{
876
 
  assert(fixed == 1);
877
 
  if (!var_entry)
878
 
    return 0;
879
 
  return var_entry->val_decimal(&null_value, dec);
880
 
}
881
 
 
882
 
 
883
 
int64_t Item_func_get_user_var::val_int()
884
 
{
885
 
  assert(fixed == 1);
886
 
  if (!var_entry)
887
 
    return 0L;                          // No such variable
888
 
  return (var_entry->val_int(&null_value));
889
 
}
890
 
 
891
 
 
892
 
/**
893
 
  Get variable by name and, if necessary, put the record of variable 
894
 
  use into the binary log.
895
 
 
896
 
  When a user variable is invoked from an update query (INSERT, UPDATE etc),
897
 
  stores this variable and its value in session->user_var_events, so that it can be
898
 
  written to the binlog (will be written just before the query is written, see
899
 
  log.cc).
900
 
 
901
 
  @param      session        Current thread
902
 
  @param      name       Variable name
903
 
  @param[out] out_entry  variable structure or NULL. The pointer is set
904
 
                         regardless of whether function succeeded or not.
905
 
 
906
 
  @retval
907
 
    0  OK
908
 
  @retval
909
 
    1  Failed to put appropriate record into binary log
910
 
 
911
 
*/
912
 
 
913
 
int get_var_with_binlog(Session *session, enum_sql_command sql_command,
914
 
                        LEX_STRING &name, user_var_entry **out_entry)
915
 
{
916
 
  BINLOG_USER_VAR_EVENT *user_var_event;
917
 
  user_var_entry *var_entry;
918
 
  var_entry= get_variable(&session->user_vars, name, 0);
919
 
 
920
 
  /*
921
 
    Any reference to user-defined variable which is done from stored
922
 
    function or trigger affects their execution and the execution of the
923
 
    calling statement. We must log all such variables even if they are 
924
 
    not involved in table-updating statements.
925
 
  */
926
 
  if (!(opt_bin_log && is_update_query(sql_command)))
927
 
  {
928
 
    *out_entry= var_entry;
929
 
    return 0;
930
 
  }
931
 
 
932
 
  if (!var_entry)
933
 
  {
934
 
    /*
935
 
      If the variable does not exist, it's NULL, but we want to create it so
936
 
      that it gets into the binlog (if it didn't, the slave could be
937
 
      influenced by a variable of the same name previously set by another
938
 
      thread).
939
 
      We create it like if it had been explicitly set with SET before.
940
 
      The 'new' mimics what sql_yacc.yy does when 'SET @a=10;'.
941
 
      sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION'
942
 
      in dispatch_command()). Instead of building a one-element list to pass to
943
 
      sql_set_variables(), we could instead manually call check() and update();
944
 
      this would save memory and time; but calling sql_set_variables() makes
945
 
      one unique place to maintain (sql_set_variables()). 
946
 
 
947
 
      Manipulation with lex is necessary since free_underlaid_joins
948
 
      is going to release memory belonging to the main query.
949
 
    */
950
 
 
951
 
    List<set_var_base> tmp_var_list;
952
 
    LEX *sav_lex= session->lex, lex_tmp;
953
 
    session->lex= &lex_tmp;
954
 
    lex_start(session);
955
 
    tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name,
956
 
                                                                       new Item_null())));
957
 
    /* Create the variable */
958
 
    if (sql_set_variables(session, &tmp_var_list))
959
 
    {
960
 
      session->lex= sav_lex;
961
 
      goto err;
962
 
    }
963
 
    session->lex= sav_lex;
964
 
    if (!(var_entry= get_variable(&session->user_vars, name, 0)))
965
 
      goto err;
966
 
  }
967
 
  else if (var_entry->used_query_id == session->query_id ||
968
 
           mysql_bin_log.is_query_in_union(session, var_entry->used_query_id))
969
 
  {
970
 
    /* 
971
 
       If this variable was already stored in user_var_events by this query
972
 
       (because it's used in more than one place in the query), don't store
973
 
       it.
974
 
    */
975
 
    *out_entry= var_entry;
976
 
    return 0;
977
 
  }
978
 
 
979
 
  uint32_t size;
980
 
  /*
981
 
    First we need to store value of var_entry, when the next situation
982
 
    appears:
983
 
    > set @a:=1;
984
 
    > insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
985
 
    We have to write to binlog value @a= 1.
986
 
 
987
 
    We allocate the user_var_event on user_var_events_alloc pool, not on
988
 
    the this-statement-execution pool because in SPs user_var_event objects 
989
 
    may need to be valid after current [SP] statement execution pool is
990
 
    destroyed.
991
 
  */
992
 
  size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
993
 
  if (!(user_var_event= (BINLOG_USER_VAR_EVENT *)
994
 
        alloc_root(session->user_var_events_alloc, size)))
995
 
    goto err;
996
 
 
997
 
  user_var_event->value= (char*) user_var_event +
998
 
    ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
999
 
  user_var_event->user_var_event= var_entry;
1000
 
  user_var_event->type= var_entry->type;
1001
 
  user_var_event->charset_number= var_entry->collation.collation->number;
1002
 
  if (!var_entry->value)
1003
 
  {
1004
 
    /* NULL value*/
1005
 
    user_var_event->length= 0;
1006
 
    user_var_event->value= 0;
1007
 
  }
1008
 
  else
1009
 
  {
1010
 
    user_var_event->length= var_entry->length;
1011
 
    memcpy(user_var_event->value, var_entry->value,
1012
 
           var_entry->length);
1013
 
  }
1014
 
  /* Mark that this variable has been used by this query */
1015
 
  var_entry->used_query_id= session->query_id;
1016
 
  if (insert_dynamic(&session->user_var_events, (unsigned char*) &user_var_event))
1017
 
    goto err;
1018
 
 
1019
 
  *out_entry= var_entry;
1020
 
  return 0;
1021
 
 
1022
 
err:
1023
 
  *out_entry= var_entry;
1024
 
  return 1;
1025
 
}
1026
 
 
1027
 
void Item_func_get_user_var::fix_length_and_dec()
1028
 
{
1029
 
  Session *session=current_session;
1030
 
  int error;
1031
 
  maybe_null=1;
1032
 
  decimals=NOT_FIXED_DEC;
1033
 
  max_length=MAX_BLOB_WIDTH;
1034
 
 
1035
 
  error= get_var_with_binlog(session, session->lex->sql_command, name, &var_entry);
1036
 
 
1037
 
  /*
1038
 
    If the variable didn't exist it has been created as a STRING-type.
1039
 
    'var_entry' is NULL only if there occured an error during the call to
1040
 
    get_var_with_binlog.
1041
 
  */
1042
 
  if (var_entry)
1043
 
  {
1044
 
    m_cached_result_type= var_entry->type;
1045
 
    unsigned_flag= var_entry->unsigned_flag;
1046
 
    max_length= var_entry->length;
1047
 
 
1048
 
    collation.set(var_entry->collation);
1049
 
    switch(m_cached_result_type) {
1050
 
    case REAL_RESULT:
1051
 
      max_length= DBL_DIG + 8;
1052
 
      break;
1053
 
    case INT_RESULT:
1054
 
      max_length= MAX_BIGINT_WIDTH;
1055
 
      decimals=0;
1056
 
      break;
1057
 
    case STRING_RESULT:
1058
 
      max_length= MAX_BLOB_WIDTH;
1059
 
      break;
1060
 
    case DECIMAL_RESULT:
1061
 
      max_length= DECIMAL_MAX_STR_LENGTH;
1062
 
      decimals= DECIMAL_MAX_SCALE;
1063
 
      break;
1064
 
    case ROW_RESULT:                            // Keep compiler happy
1065
 
    default:
1066
 
      assert(0);
1067
 
      break;
1068
 
    }
1069
 
  }
1070
 
  else
1071
 
  {
1072
 
    collation.set(&my_charset_bin, DERIVATION_IMPLICIT);
1073
 
    null_value= 1;
1074
 
    m_cached_result_type= STRING_RESULT;
1075
 
    max_length= MAX_BLOB_WIDTH;
1076
 
  }
1077
 
}
1078
 
 
1079
 
 
1080
 
bool Item_func_get_user_var::const_item() const
1081
 
{
1082
 
  return (!var_entry || current_session->query_id != var_entry->update_query_id);
1083
 
}
1084
 
 
1085
 
 
1086
 
enum Item_result Item_func_get_user_var::result_type() const
1087
 
{
1088
 
  return m_cached_result_type;
1089
 
}
1090
 
 
1091
 
 
1092
 
void Item_func_get_user_var::print(String *str,
1093
 
                                   enum_query_type query_type __attribute__((unused)))
1094
 
{
1095
 
  str->append(STRING_WITH_LEN("(@"));
1096
 
  str->append(name.str,name.length);
1097
 
  str->append(')');
1098
 
}
1099
 
 
1100
 
 
1101
 
bool Item_func_get_user_var::eq(const Item *item,
1102
 
                                bool binary_cmp __attribute__((unused))) const
1103
 
{
1104
 
  /* Assume we don't have rtti */
1105
 
  if (this == item)
1106
 
    return 1;                                   // Same item is same.
1107
 
  /* Check if other type is also a get_user_var() object */
1108
 
  if (item->type() != FUNC_ITEM ||
1109
 
      ((Item_func*) item)->functype() != functype())
1110
 
    return 0;
1111
 
  Item_func_get_user_var *other=(Item_func_get_user_var*) item;
1112
 
  return (name.length == other->name.length &&
1113
 
          !memcmp(name.str, other->name.str, name.length));
1114
 
}
1115
 
 
1116
 
 
1117
802
bool Item_user_var_as_out_param::fix_fields(Session *session, Item **ref)
1118
803
{
1119
804
  assert(fixed == 0);
1201
886
    - 0  : error
1202
887
    - #  : constant item
1203
888
*/
1204
 
 
1205
 
 
1206
 
int64_t Item_func_found_rows::val_int()
1207
 
{
1208
 
  assert(fixed == 1);
1209
 
  Session *session= current_session;
1210
 
 
1211
 
  return session->found_rows();
1212
 
}