Drizzled Public API Documentation

insert.cc

00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <drizzled/function/str/insert.h>
00023 #include <drizzled/error.h>
00024 #include <drizzled/session.h>
00025 
00026 namespace drizzled
00027 {
00028 
00029 String *Item_func_insert::val_str(String *str)
00030 {
00031   assert(fixed == 1);
00032   String *res,*res2;
00033   int64_t start, length;  /* must be int64_t to avoid truncation */
00034 
00035   null_value=0;
00036   res=args[0]->val_str(str);
00037   res2=args[3]->val_str(&tmp_value);
00038   start= args[1]->val_int() - 1;
00039   length= args[2]->val_int();
00040 
00041   if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
00042       args[3]->null_value)
00043     goto null;
00044 
00045   if ((start < 0) || (start > static_cast<int64_t>(res->length())))
00046     return res;                                 // Wrong param; skip insert
00047   if ((length < 0) || (length > static_cast<int64_t>(res->length())))
00048     length= res->length();
00049 
00050   /* start and length are now sufficiently valid to pass to charpos function */
00051    start= res->charpos((int) start);
00052    length= res->charpos((int) length, (uint32_t) start);
00053 
00054   /* Re-testing with corrected params */
00055   if (start > static_cast<int64_t>(res->length()))
00056     return res;
00057   if (length > static_cast<int64_t>(res->length()) - start)
00058     length= res->length() - start;
00059 
00060   if ((uint64_t) (res->length() - length + res2->length()) >
00061       (uint64_t) session.variables.max_allowed_packet)
00062   {
00063     push_warning_printf(&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
00064       ER_WARN_ALLOWED_PACKET_OVERFLOWED,
00065       ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
00066       func_name(), session.variables.max_allowed_packet);
00067     goto null;
00068   }
00069   res=copy_if_not_alloced(str,res,res->length());
00070   res->replace((uint32_t) start,(uint32_t) length,*res2);
00071   return res;
00072 null:
00073   null_value=1;
00074   return 0;
00075 }
00076 
00077 
00078 void Item_func_insert::fix_length_and_dec()
00079 {
00080   uint64_t max_result_length;
00081 
00082   // Handle character set for args[0] and args[3].
00083   if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 3))
00084     return;
00085   max_result_length= ((uint64_t) args[0]->max_length+
00086                       (uint64_t) args[3]->max_length);
00087   if (max_result_length >= MAX_BLOB_WIDTH)
00088   {
00089     max_result_length= MAX_BLOB_WIDTH;
00090     maybe_null= 1;
00091   }
00092   max_length= (ulong) max_result_length;
00093 }
00094 
00095 } /* namespace drizzled */