00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <plugin/function_engine/cursor.h>
00024 #include <drizzled/session.h>
00025 #include <drizzled/internal/my_sys.h>
00026 #include <drizzled/field/blob.h>
00027 #include <drizzled/table.h>
00028 #include <drizzled/statistics_variables.h>
00029
00030 #include <unistd.h>
00031 #include <fcntl.h>
00032
00033 #include <string>
00034
00035 using namespace std;
00036 using namespace drizzled;
00037
00038
00039
00040
00041
00042 FunctionCursor::FunctionCursor(plugin::StorageEngine &engine_arg,
00043 Table &table_arg) :
00044 Cursor(engine_arg, table_arg),
00045 estimate_of_rows(100),
00046 rows_returned(0)
00047 {}
00048
00049 int FunctionCursor::open(const char *name, int, uint32_t)
00050 {
00051 tool= static_cast<Function *>(getEngine())->getFunction(name);
00052
00053
00054 row_cache_position= 0;
00055
00056 if (not tool)
00057 return HA_ERR_NO_SUCH_TABLE;
00058
00059 return 0;
00060 }
00061
00062 int FunctionCursor::close(void)
00063 {
00064 tool= NULL;
00065 wipeCache();
00066
00067 return 0;
00068 }
00069
00070 int FunctionCursor::doStartTableScan(bool)
00071 {
00072 rows_returned= 0;
00073 generator= tool->generator(getTable()->getFields());
00074
00075 return 0;
00076 }
00077
00078
00079 int FunctionCursor::rnd_next(unsigned char *)
00080 {
00081 bool more_rows;
00082 ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
00083
00084
00085 for (Field **field= getTable()->getFields() ; *field ; field++)
00086 {
00087 (*field)->setWriteSet();
00088 }
00089
00090 more_rows= generator->sub_populate(getTable()->getShare()->sizeFields());
00091
00092 if (more_rows)
00093 {
00094 return 0;
00095 }
00096 else
00097 {
00098 delete generator;
00099 generator= NULL;
00100 }
00101 rows_returned++;
00102
00103 return more_rows ? 0 : HA_ERR_END_OF_FILE;
00104 }
00105
00106 uint32_t FunctionCursor::max_row_length()
00107 {
00108 uint32_t length= (uint32_t)(getTable()->getRecordLength() + getTable()->sizeFields()*2);
00109
00110 uint32_t *ptr, *end;
00111 for (ptr= getTable()->getBlobField(), end=ptr + getTable()->sizeBlobFields();
00112 ptr != end ;
00113 ptr++)
00114 {
00115 length += 2 + ((Field_blob*)getTable()->getField(*ptr))->get_length();
00116 }
00117
00118 return length;
00119 }
00120
00121 unsigned int FunctionCursor::pack_row(const unsigned char *record)
00122 {
00123 unsigned char *ptr;
00124
00125 record_buffer.resize(max_row_length());
00126
00127
00128 memcpy(&record_buffer[0], record, getTable()->getShare()->null_bytes);
00129 ptr= &record_buffer[0] + getTable()->getShare()->null_bytes;
00130
00131 for (Field **field=getTable()->getFields() ; *field ; field++)
00132 {
00133 if (!((*field)->is_null()))
00134 ptr= (*field)->pack(ptr, record + (*field)->offset(record));
00135 }
00136
00137 return((unsigned int) (ptr - &record_buffer[0]));
00138 }
00139
00140 void FunctionCursor::position(const unsigned char *record)
00141 {
00142 uint32_t max_length= max_row_length();
00143
00144 if (row_cache.size() <= row_cache_position + max_length)
00145 {
00146 row_cache.resize(row_cache.size() + max_length);
00147 }
00148
00149 unsigned int r_pack_length;
00150 r_pack_length= pack_row(record);
00151 internal::my_store_ptr(ref, ref_length, row_cache_position);
00152
00153 memcpy(&row_cache[row_cache_position], &record_buffer[0], r_pack_length);
00154 row_cache_position+= r_pack_length;
00155 }
00156
00157
00158 void FunctionCursor::wipeCache()
00159 {
00160 if (rows_returned > estimate_of_rows)
00161 estimate_of_rows= rows_returned;
00162
00163 row_cache.clear();
00164 row_cache_position= 0;
00165 }
00166
00167 int FunctionCursor::extra(enum ha_extra_function operation)
00168 {
00169 switch (operation)
00170 {
00171 case drizzled::HA_EXTRA_CACHE:
00172 break;
00173 case drizzled::HA_EXTRA_NO_CACHE:
00174 break;
00175 case drizzled::HA_EXTRA_RESET_STATE:
00176 wipeCache();
00177 break;
00178 default:
00179 break;
00180 }
00181
00182 return 0;
00183 }
00184
00185 int FunctionCursor::doEndTableScan()
00186 {
00187 delete generator;
00188
00189 return 0;
00190 }
00191
00192 int FunctionCursor::rnd_pos(unsigned char *buf, unsigned char *pos)
00193 {
00194 ha_statistic_increment(&system_status_var::ha_read_rnd_count);
00195 size_t position_id= (size_t)internal::my_get_ptr(pos, ref_length);
00196
00197 const unsigned char *ptr;
00198 ptr= &row_cache[position_id];
00199
00200
00201 memcpy(buf, ptr, getTable()->getNullBytes());
00202 ptr+= getTable()->getNullBytes();
00203
00204 for (Field **field= getTable()->getFields() ; *field ; field++)
00205 {
00206 if (!((*field)->is_null()))
00207 {
00208 ptr= (*field)->unpack(buf + (*field)->offset(getTable()->getInsertRecord()), ptr);
00209 }
00210 }
00211
00212 return 0;
00213 }
00214
00215
00216 int FunctionCursor::info(uint32_t flag)
00217 {
00218 memset(&stats, 0, sizeof(stats));
00219
00220 if (flag & HA_STATUS_AUTO)
00221 stats.auto_increment_value= 1;
00222
00223 stats.records= estimate_of_rows;
00224
00225 return 0;
00226 }