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 <drizzled/field/blob.h>
00024 #include <drizzled/join_table.h>
00025 #include <drizzled/sql_lex.h>
00026 #include <drizzled/sql_select.h>
00027 #include <drizzled/table.h>
00028 #include <drizzled/util/test.h>
00029
00030 namespace drizzled
00031 {
00032
00033 int JoinTable::joinReadConstTable(optimizer::Position *pos)
00034 {
00035 int error;
00036 Table *Table= this->table;
00037 Table->const_table=1;
00038 Table->null_row=0;
00039 Table->status=STATUS_NO_RECORD;
00040
00041 if (this->type == AM_SYSTEM)
00042 {
00043 if ((error=this->joinReadSystem()))
00044 {
00045 this->info="const row not found";
00046
00047 pos->setFanout(0.0);
00048 pos->clearRefDependMap();
00049 if (! Table->maybe_null || error > 0)
00050 return(error);
00051 }
00052 }
00053 else
00054 {
00055 if (! Table->key_read &&
00056 Table->covering_keys.test(this->ref.key) &&
00057 ! Table->no_keyread &&
00058 (int) Table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
00059 {
00060 Table->key_read=1;
00061 Table->cursor->extra(HA_EXTRA_KEYREAD);
00062 this->index= this->ref.key;
00063 }
00064 error=join_read_const(this);
00065 if (Table->key_read)
00066 {
00067 Table->key_read=0;
00068 Table->cursor->extra(HA_EXTRA_NO_KEYREAD);
00069 }
00070 if (error)
00071 {
00072 this->info="unique row not found";
00073
00074 pos->setFanout(0.0);
00075 pos->clearRefDependMap();
00076 if (!Table->maybe_null || error > 0)
00077 return(error);
00078 }
00079 }
00080 if (*this->on_expr_ref && !Table->null_row)
00081 {
00082 if ((Table->null_row= test((*this->on_expr_ref)->val_int() == 0)))
00083 Table->mark_as_null_row();
00084 }
00085 if (!Table->null_row)
00086 Table->maybe_null=0;
00087
00088
00089 Join *Join= this->join;
00090 if (Join->conds)
00091 update_const_equal_items(Join->conds, this);
00092 TableList *tbl;
00093 for (tbl= Join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
00094 {
00095 TableList *embedded;
00096 TableList *embedding= tbl;
00097 do
00098 {
00099 embedded= embedding;
00100 if (embedded->on_expr)
00101 update_const_equal_items(embedded->on_expr, this);
00102 embedding= embedded->getEmbedding();
00103 }
00104 while (embedding &&
00105 &embedding->getNestedJoin()->join_list.front() == embedded);
00106 }
00107
00108 return(0);
00109 }
00110
00111 void JoinTable::readCachedRecord()
00112 {
00113 unsigned char *pos;
00114 uint32_t length;
00115 bool last_record;
00116 CacheField *copy,*end_field;
00117
00118 last_record= this->cache.record_nr++ == this->cache.ptr_record;
00119 pos= this->cache.pos;
00120 for (copy= this->cache.field, end_field= copy+this->cache.fields;
00121 copy < end_field;
00122 copy++)
00123 {
00124 if (copy->blob_field)
00125 {
00126 if (last_record)
00127 {
00128 copy->blob_field->set_image(pos, copy->length+sizeof(char*),
00129 copy->blob_field->charset());
00130 pos+=copy->length+sizeof(char*);
00131 }
00132 else
00133 {
00134 copy->blob_field->set_ptr(pos, pos+copy->length);
00135 pos+=copy->length+copy->blob_field->get_length();
00136 }
00137 }
00138 else
00139 {
00140 if (copy->strip)
00141 {
00142 length= uint2korr(pos);
00143 memcpy(copy->str, pos+2, length);
00144 memset(copy->str+length, ' ', copy->length-length);
00145 pos+= 2 + length;
00146 }
00147 else
00148 {
00149 memcpy(copy->str,pos,copy->length);
00150 pos+=copy->length;
00151 }
00152 }
00153 }
00154 this->cache.pos=pos;
00155 }
00156
00157 int JoinTable::joinReadSystem()
00158 {
00159 Table *Table= this->table;
00160 int error;
00161 if (Table->status & STATUS_GARBAGE)
00162 {
00163 if ((error=Table->cursor->read_first_row(table->getInsertRecord(),
00164 Table->getShare()->getPrimaryKey())))
00165 {
00166 if (error != HA_ERR_END_OF_FILE)
00167 return Table->report_error(error);
00168 this->table->mark_as_null_row();
00169 Table->emptyRecord();
00170 return -1;
00171 }
00172 Table->storeRecord();
00173 }
00174 else if (!Table->status)
00175 Table->restoreRecord();
00176 Table->null_row=0;
00177 return Table->status ? -1 : 0;
00178 }
00179
00180 }