corrected to accept hostname and connect to network
[csql.git] / src / storage / AggTableImpl.cxx
blobb6217d980cecbc31a3b4162a4d8f53e40bf222c4
1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 ***************************************************************************/
16 #include<Debug.h>
17 #include<Table.h>
18 #include<TableImpl.h>
19 #include<AggTableImpl.h>
20 AggTableImpl::AggTableImpl()
23 AggTableImpl::~AggTableImpl()
26 void *AggTableImpl::getBindFldAddr(const char *name)
28 return NULL;
33 DbRetVal AggTableImpl::bindFld(const char *name, void *val)
35 return ErrBadCall;
37 DbRetVal AggTableImpl::bindFld(const char *fldname, AggType aggType, void *val)
39 FieldInfo *info = new FieldInfo();
40 tableHdl->getFieldInfo(fldname, info);
41 AggFldDef *def = new AggFldDef();
42 strcpy(def->fldName, fldname);
43 def->type = info->type;
44 def->length= info->length;
45 def->appBuf = val;
46 def->atype=aggType;
47 def->bindBuf = NULL;
48 def->alreadyBinded = false;
49 ListIterator iter = fldList.getIterator();
50 AggFldDef *elem;
51 //If it is already binded, then use the same buffer which is binded.
52 //this code is to handle statements which have more aggregates on same field
53 while (iter.hasElement())
55 elem = (AggFldDef*) iter.nextElement();
56 if (strcmp(elem->fldName, fldname)==0)
58 def->bindBuf = elem->bindBuf;
59 def->alreadyBinded = true;
60 break;
63 if (!def->bindBuf)
65 def->bindBuf = AllDataType::alloc(def->type, def->length);
66 tableHdl->bindFld(fldname, def->bindBuf);
68 fldList.append(def);
69 delete info;
70 return OK;
72 DbRetVal AggTableImpl::setGroup(const char *fldname, void *val)
74 FieldInfo *info = new FieldInfo();
75 tableHdl->getFieldInfo(fldname, info);
76 strcpy(groupFld.fldName, fldname);
77 groupFld.type = info->type;
78 groupFld.length = info->length;
79 groupFld.appBuf = val;
80 groupFld.bindBuf = AllDataType::alloc(info->type, info->length);
81 tableHdl->bindFld(fldname, groupFld.bindBuf);
82 delete info;
83 return OK;
86 DbRetVal AggTableImpl::execute()
88 ListIterator iter = fldList.getIterator();
89 AggFldDef *def;
90 if (isGroupSet())
91 aggNodeSize = AllDataType::size(groupFld.type, groupFld.length);
92 else
93 aggNodeSize = 0;
94 while (iter.hasElement())
96 def = (AggFldDef*) iter.nextElement();
97 aggNodeSize = aggNodeSize + AllDataType::size(def->type, def->length);
98 if (def->atype == AGG_AVG) aggNodeSize = aggNodeSize + sizeof(int);//for count
100 void *tuple = NULL;
101 int offset=0;
102 tableHdl->execute();
103 aggNodes.reset();
104 while((tuple = tableHdl->fetch()) != NULL)
106 char *buffer = (char*)insertOrGet();
107 iter.reset();
108 if (isGroupSet())
109 offset = AllDataType::size(groupFld.type, groupFld.length);
110 else
111 offset = 0;
112 while (iter.hasElement())
114 def = (AggFldDef*) iter.nextElement();
115 switch(def->atype)
117 case AGG_MIN: {
118 bool result = AllDataType::compareVal(buffer+offset,
119 def->bindBuf, OpGreaterThan, def->type, def->length);
120 if (result)
121 AllDataType::copyVal(buffer+offset, def->bindBuf,
122 def->type, def->length);
123 break;
125 case AGG_MAX: {
126 bool result = AllDataType::compareVal(buffer+offset,
127 def->bindBuf, OpLessThan, def->type, def->length);
128 if (result)
129 AllDataType::copyVal(buffer+offset, def->bindBuf,
130 def->type, def->length);
131 break;
133 case AGG_SUM: {
134 AllDataType::addVal(buffer+offset, def->bindBuf, def->type);
135 break;
137 case AGG_AVG: {
138 AllDataType::addVal(buffer+offset, def->bindBuf, def->type);
139 (*(int*)(buffer+offset + AllDataType::size(def->type, def->length)))++;
140 offset = offset +sizeof(int); //->count
141 break;
143 case AGG_COUNT:
144 (*(int*)(buffer+offset))++;
145 break;
147 offset = offset + AllDataType::size(def->type, def->length);
150 aggNodeIter = aggNodes.getIterator();
151 iter.reset();
152 char *element;
153 while (iter.hasElement()) {
154 def = (AggFldDef*) iter.nextElement();
155 if (isGroupSet())
156 offset = AllDataType::size(groupFld.type, groupFld.length);
157 else
158 offset = 0;
159 switch(def->atype)
161 case AGG_AVG: {
162 while (aggNodeIter.hasElement()) {
163 element = (char*)aggNodeIter.nextElement();
164 AllDataType::divVal(element+offset,
165 *(int*)(element+offset+AllDataType::size(def->type, def->length)),
166 def->type);
168 offset = offset +sizeof(int);
171 offset = offset + AllDataType::size(def->type, def->length);
173 aggNodeIter.reset();
174 tableHdl->close();
175 return OK;
177 void* AggTableImpl::insertOrGet()
179 ListIterator aiter = aggNodes.getIterator();
180 char *element;
181 while (aiter.hasElement()) {
182 element = (char*)aiter.nextElement();
184 if (!isGroupSet()) return element;
185 if (AllDataType::compareVal(element, groupFld.bindBuf, OpEquals,
186 groupFld.type, groupFld.length))
188 return element;
191 element = (char*)malloc(aggNodeSize);
192 ListIterator iter = fldList.getIterator();
193 AggFldDef *def;
194 char *offset;
195 if (isGroupSet()) {
196 AllDataType::copyVal(element, groupFld.bindBuf, groupFld.type,
197 groupFld.length);
198 offset = element + AllDataType::size(groupFld.type, groupFld.length);
200 else
201 offset = element;
203 while (iter.hasElement())
205 def = (AggFldDef*) iter.nextElement();
206 switch(def->atype) {
207 case AGG_MIN: { *(int*)(offset)=INT_MAX; break; }
208 case AGG_MAX: { *(int*)(offset)=INT_MIN; break; }
209 case AGG_SUM: { *(int*)(offset)=0; break; }
210 case AGG_AVG: {
211 *(int*)(offset)=0;
212 *(int*)(offset+AllDataType::size(def->type, def->length))=0; //count
213 offset = offset+ sizeof(int);
214 break;
216 case AGG_COUNT: { *(int*)(offset)=0; break; }
218 offset = offset + AllDataType::size(def->type, def->length);
220 aggNodes.append(element);
221 return element;
224 void* AggTableImpl::fetch()
226 if(aggNodeIter.hasElement())
228 void *elem = aggNodeIter.nextElement();
229 copyValuesToBindBuffer(elem);
230 return elem;
232 else
233 return NULL;
236 void* AggTableImpl::fetch(DbRetVal &rv)
238 rv = OK;
239 return fetch();
242 void* AggTableImpl::fetchNoBind()
244 if(aggNodeIter.hasElement())
246 void *elem = aggNodeIter.nextElement();
247 return elem;
249 else
250 return NULL;
253 void* AggTableImpl::fetchNoBind(DbRetVal &rv)
255 rv = OK;
256 return fetchNoBind();
259 DbRetVal AggTableImpl::copyValuesToBindBuffer(void *elem)
261 char *element = (char*)elem;
262 //Iterate through the bind list and copy the value here
263 ListIterator fIter = fldList.getIterator();
264 AggFldDef *def;
265 AllDataType::copyVal(groupFld.appBuf, elem, groupFld.type, groupFld.length);
266 char *colPtr = (char*) elem + AllDataType::size(groupFld.type, groupFld.length);
267 while (fIter.hasElement())
269 def = (AggFldDef*) fIter.nextElement();
270 if (NULL != def->appBuf) {
271 AllDataType::copyVal(def->appBuf, colPtr, def->type, def->length);
273 colPtr = colPtr + os::align(AllDataType::size(def->type, def->length));
274 if(def->atype == AGG_AVG) colPtr = colPtr + sizeof(int);
276 return OK;
279 long AggTableImpl::numTuples()
281 return aggNodes.size();
283 void AggTableImpl::closeScan()
285 aggNodeIter.reset();
286 ListIterator aiter = aggNodes.getIterator();
287 char *element;
288 while (aiter.hasElement()) {
289 element = (char*)aiter.nextElement();
290 free(element);
292 aggNodes.reset();
295 DbRetVal AggTableImpl::close()
297 //free memory allocated. make sure that field buffers are freed only once.
298 //for stmts which has more than one agg on same field needs to be handled safely
299 free(groupFld.bindBuf);
300 ListIterator iter = fldList.getIterator();
301 AggFldDef *elem;
302 while (iter.hasElement())
304 elem = (AggFldDef*) iter.nextElement();
305 if(!elem->alreadyBinded) free(elem->bindBuf);
307 fldList.reset();
308 return OK;