~drizzle-trunk/drizzle/development

139.1.9 by Stewart Smith
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test
1
/* Copyright (C) 2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
520.1.22 by Brian Aker
Second pass of thd cleanup
16
#define DRIZZLE_SERVER 1 /* for session variable max_allowed_packet */
139.1.9 by Stewart Smith
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test
17
#include <drizzled/server_includes.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
18
#include <drizzled/session.h>
549 by Monty Taylor
Took gettext.h out of header files.
19
#include <drizzled/error.h>
584.4.7 by Monty Taylor
Removed a big bank of includes from item.h.
20
#include <drizzled/item/strfunc.h>
139.1.9 by Stewart Smith
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test
21
22
#include <zlib.h>
23
24
class Item_func_uncompress: public Item_str_func
25
{
26
  String buffer;
27
public:
28
  Item_func_uncompress(): Item_str_func(){}
29
  void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
30
  const char *func_name() const{return "uncompress";}
31
  String *val_str(String *) ;
32
};
33
34
String *Item_func_uncompress::val_str(String *str)
35
{
36
  assert(fixed == 1);
37
  String *res= args[0]->val_str(str);
38
  ulong new_size;
39
  int err;
482 by Brian Aker
Remove uint.
40
  uint32_t code;
139.1.9 by Stewart Smith
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test
41
42
  if (!res)
43
    goto err;
44
  null_value= 0;
45
  if (res->is_empty())
46
    return res;
47
48
  /* If length is less than 4 bytes, data is corrupt */
49
  if (res->length() <= 4)
50
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
51
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
52
                        ER_ZLIB_Z_DATA_ERROR,
53
                        ER(ER_ZLIB_Z_DATA_ERROR));
139.1.9 by Stewart Smith
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test
54
    goto err;
55
  }
56
57
  /* Size of uncompressed data is stored as first 4 bytes of field */
58
  new_size= uint4korr(res->ptr()) & 0x3FFFFFFF;
520.1.22 by Brian Aker
Second pass of thd cleanup
59
  if (new_size > current_session->variables.max_allowed_packet)
139.1.9 by Stewart Smith
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test
60
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
61
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
62
                        ER_TOO_BIG_FOR_UNCOMPRESS,
63
                        ER(ER_TOO_BIG_FOR_UNCOMPRESS),
520.1.22 by Brian Aker
Second pass of thd cleanup
64
                        current_session->variables.max_allowed_packet);
139.1.9 by Stewart Smith
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test
65
    goto err;
66
  }
67
  if (buffer.realloc((uint32_t)new_size))
68
    goto err;
69
70
  if ((err= uncompress((Byte*)buffer.ptr(), &new_size,
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
71
                       ((const Bytef*)res->ptr())+4,res->length())) == Z_OK)
139.1.9 by Stewart Smith
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test
72
  {
73
    buffer.length((uint32_t) new_size);
74
    return &buffer;
75
  }
76
77
  code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR :
78
	 ((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR));
520.1.22 by Brian Aker
Second pass of thd cleanup
79
  push_warning(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR, code, ER(code));
139.1.9 by Stewart Smith
Move compression functions (compress, uncompress and compressed_length) out into modules and fix test
80
81
err:
82
  null_value= 1;
83
  return 0;
84
}
85
86
87
Item_func* create_uncompressudf_item(MEM_ROOT* m)
88
{
89
  return  new (m) Item_func_uncompress();
90
}
91
92
static struct udf_func uncompressudf = {
93
  { C_STRING_WITH_LEN("uncompress") },
94
  create_uncompressudf_item
95
};
96
97
static int uncompressudf_plugin_init(void *p)
98
{
99
  udf_func **f = (udf_func**) p;
100
101
  *f= &uncompressudf;
102
103
  return 0;
104
}
105
106
static int uncompressudf_plugin_deinit(void *p)
107
{
108
  udf_func *udff = (udf_func *) p;
109
  (void)udff;
110
  return 0;
111
}
112
113
mysql_declare_plugin(uncompress)
114
{
115
  DRIZZLE_UDF_PLUGIN,
116
  "uncompress",
117
  "1.0",
118
  "Stewart Smith",
119
  "UDF for compress()",
120
  PLUGIN_LICENSE_GPL,
121
  uncompressudf_plugin_init, /* Plugin Init */
122
  uncompressudf_plugin_deinit, /* Plugin Deinit */
123
  NULL,   /* status variables */
124
  NULL,   /* system variables */
125
  NULL    /* config options */
126
}
127
mysql_declare_plugin_end;