1 /***************************************************************************
2 * Copyright (C) 2007 by www.databasecache.com *
3 * Contact: praba_tuty@databasecache.com *
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. *
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. *
15 ***************************************************************************/
19 #include<AggTableImpl.h>
20 AggTableImpl::AggTableImpl()
23 AggTableImpl::~AggTableImpl()
27 void *AggTableImpl::getBindFldAddr(const char *name
)
29 printError(ErrBadCall
, "AggTableImpl getBindFldAdddr not implemented\n");
35 DbRetVal
AggTableImpl::bindFld(const char *name
, void *val
)
37 printError(ErrBadCall
, "AggTableImpl bindFld not implemented\n");
40 DbRetVal
AggTableImpl::bindFld(const char *fldname
, AggType aggType
, void *val
)
42 FieldInfo
*info
= new FieldInfo();
43 tableHdl
->getFieldInfo(fldname
, info
);
44 AggFldDef
*def
= new AggFldDef();
45 strcpy(def
->fldName
, fldname
);
46 def
->type
= info
->type
;
47 def
->length
= info
->length
;
51 def
->alreadyBinded
= false;
52 ListIterator iter
= fldList
.getIterator();
54 //If it is already binded, then use the same buffer which is binded.
55 //this code is to handle statements which have more aggregates on same field
56 while (iter
.hasElement())
58 elem
= (AggFldDef
*) iter
.nextElement();
59 if (strcmp(elem
->fldName
, fldname
)==0)
61 def
->bindBuf
= elem
->bindBuf
;
62 def
->alreadyBinded
= true;
68 def
->bindBuf
= AllDataType::alloc(def
->type
, def
->length
);
69 tableHdl
->bindFld(fldname
, def
->bindBuf
);
75 DbRetVal
AggTableImpl::setGroup(const char *fldname
, void *val
)
77 FieldInfo
*info
= new FieldInfo();
78 tableHdl
->getFieldInfo(fldname
, info
);
79 strcpy(groupFld
.fldName
, fldname
);
80 groupFld
.type
= info
->type
;
81 groupFld
.length
= info
->length
;
82 groupFld
.appBuf
= val
;
83 groupFld
.bindBuf
= AllDataType::alloc(info
->type
, info
->length
);
84 tableHdl
->bindFld(fldname
, groupFld
.bindBuf
);
89 DbRetVal
AggTableImpl::execute()
91 ListIterator iter
= fldList
.getIterator();
94 aggNodeSize
= AllDataType::size(groupFld
.type
, groupFld
.length
);
97 while (iter
.hasElement())
99 def
= (AggFldDef
*) iter
.nextElement();
100 aggNodeSize
= aggNodeSize
+ AllDataType::size(def
->type
, def
->length
);
101 if (def
->atype
== AGG_AVG
) aggNodeSize
= aggNodeSize
+ sizeof(int);//for count
107 while((tuple
= tableHdl
->fetch()) != NULL
)
109 char *buffer
= (char*)insertOrGet();
112 offset
= AllDataType::size(groupFld
.type
, groupFld
.length
);
115 while (iter
.hasElement())
117 def
= (AggFldDef
*) iter
.nextElement();
121 bool result
= AllDataType::compareVal(buffer
+offset
,
122 def
->bindBuf
, OpGreaterThan
, def
->type
, def
->length
);
124 AllDataType::copyVal(buffer
+offset
, def
->bindBuf
,
125 def
->type
, def
->length
);
129 bool result
= AllDataType::compareVal(buffer
+offset
,
130 def
->bindBuf
, OpLessThan
, def
->type
, def
->length
);
132 AllDataType::copyVal(buffer
+offset
, def
->bindBuf
,
133 def
->type
, def
->length
);
137 AllDataType::addVal(buffer
+offset
, def
->bindBuf
, def
->type
);
141 AllDataType::addVal(buffer
+offset
, def
->bindBuf
, def
->type
);
142 (*(int*)(buffer
+offset
+ AllDataType::size(def
->type
, def
->length
)))++;
143 offset
= offset
+sizeof(int); //->count
147 (*(int*)(buffer
+offset
))++;
148 if ((*(int*)(buffer
+offset
)) % 1000000 ==0)
149 printf("PRABA:%d\n", (*(int*)(buffer
+offset
)));
152 offset
= offset
+ AllDataType::size(def
->type
, def
->length
);
155 aggNodeIter
= aggNodes
.getIterator();
158 while (iter
.hasElement()) {
159 def
= (AggFldDef
*) iter
.nextElement();
161 offset
= AllDataType::size(groupFld
.type
, groupFld
.length
);
167 while (aggNodeIter
.hasElement()) {
168 element
= (char*)aggNodeIter
.nextElement();
169 AllDataType::divVal(element
+offset
,
170 *(int*)(element
+offset
+AllDataType::size(def
->type
, def
->length
)),
173 offset
= offset
+sizeof(int);
176 offset
= offset
+ AllDataType::size(def
->type
, def
->length
);
182 void* AggTableImpl::insertOrGet()
184 ListIterator aiter
= aggNodes
.getIterator();
186 while (aiter
.hasElement()) {
187 element
= (char*)aiter
.nextElement();
189 if (!isGroupSet()) return element
;
190 if (AllDataType::compareVal(element
, groupFld
.bindBuf
, OpEquals
,
191 groupFld
.type
, groupFld
.length
))
196 element
= (char*)malloc(aggNodeSize
);
197 ListIterator iter
= fldList
.getIterator();
201 AllDataType::copyVal(element
, groupFld
.bindBuf
, groupFld
.type
,
203 offset
= element
+ AllDataType::size(groupFld
.type
, groupFld
.length
);
208 while (iter
.hasElement())
210 def
= (AggFldDef
*) iter
.nextElement();
212 case AGG_MIN
: { *(int*)(offset
)=INT_MAX
; break; }
213 case AGG_MAX
: { *(int*)(offset
)=INT_MIN
; break; }
214 case AGG_SUM
: { *(int*)(offset
)=0; break; }
217 *(int*)(offset
+AllDataType::size(def
->type
, def
->length
))=0; //count
218 offset
= offset
+ sizeof(int);
221 case AGG_COUNT
: { *(int*)(offset
)=0; break; }
223 offset
= offset
+ AllDataType::size(def
->type
, def
->length
);
225 aggNodes
.append(element
);
229 void* AggTableImpl::fetch()
231 if(aggNodeIter
.hasElement())
233 void *elem
= aggNodeIter
.nextElement();
234 copyValuesToBindBuffer(elem
);
241 void* AggTableImpl::fetch(DbRetVal
&rv
)
247 void* AggTableImpl::fetchNoBind()
249 if(aggNodeIter
.hasElement())
251 void *elem
= aggNodeIter
.nextElement();
258 void* AggTableImpl::fetchNoBind(DbRetVal
&rv
)
261 return fetchNoBind();
264 DbRetVal
AggTableImpl::copyValuesToBindBuffer(void *elem
)
266 char *element
= (char*)elem
;
267 //Iterate through the bind list and copy the value here
268 ListIterator fIter
= fldList
.getIterator();
270 AllDataType::copyVal(groupFld
.appBuf
, elem
, groupFld
.type
, groupFld
.length
);
271 char *colPtr
= (char*) elem
+ AllDataType::size(groupFld
.type
, groupFld
.length
);
272 while (fIter
.hasElement())
274 def
= (AggFldDef
*) fIter
.nextElement();
275 if (NULL
!= def
->appBuf
) {
276 AllDataType::copyVal(def
->appBuf
, colPtr
, def
->type
, def
->length
);
278 colPtr
= colPtr
+ os::align(AllDataType::size(def
->type
, def
->length
));
279 if(def
->atype
== AGG_AVG
) colPtr
= colPtr
+ sizeof(int);
284 long AggTableImpl::numTuples()
286 return aggNodes
.size();
288 DbRetVal
AggTableImpl::closeScan()
291 ListIterator aiter
= aggNodes
.getIterator();
293 while (aiter
.hasElement()) {
294 element
= (char*)aiter
.nextElement();
298 tableHdl
->closeScan();
301 DbRetVal
AggTableImpl::close()
303 //free memory allocated. make sure that field buffers are freed only once.
304 //for stmts which has more than one agg on same field needs to be handled safely
306 free(groupFld
.bindBuf
);
307 groupFld
.bindBuf
= NULL
;
308 ListIterator iter
= fldList
.getIterator();
310 while (iter
.hasElement())
312 elem
= (AggFldDef
*) iter
.nextElement();
313 //if(!elem->alreadyBinded) free(elem->bindBuf);
314 //TEMPHACK:PRABA::to avoid cordump in odbcBench