00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "oql_p.h"
00026
00027
00028
00029
00030
00031
00032
00033 namespace eyedb {
00034
00035 oqmlColl::oqmlColl(oqml_List * _list, oqmlTYPE _type) : oqmlNode(_type)
00036 {
00037 list = _list;
00038 }
00039
00040 oqmlColl::~oqmlColl()
00041 {
00042 delete list;
00043 }
00044
00045 oqmlStatus *oqmlColl::compile(Database *db, oqmlContext *ctx)
00046 {
00047 if (!list)
00048 return oqmlSuccess;
00049
00050 oqml_Link *l = list->first;
00051
00052 while (l)
00053 {
00054 oqmlStatus *s;
00055
00056 if ((s = l->ql->compile(db, ctx)) != oqmlSuccess)
00057 return s;
00058
00059 l = l->next;
00060 }
00061
00062 return oqmlSuccess;
00063 }
00064
00065 oqmlStatus *oqmlColl::eval(Database *db, oqmlContext *ctx,
00066 oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00067 {
00068 if (!list)
00069 {
00070 *alist = new oqmlAtomList(makeAtomColl(new oqmlAtomList()));
00071 return oqmlSuccess;
00072 }
00073
00074 oqml_Link *l = list->first;
00075 oqmlAtomList *al = new oqmlAtomList();
00076
00077 while (l)
00078 {
00079 oqml_Link *next = l->next;
00080 oqmlAtomList *tal;
00081 oqmlStatus *s;
00082
00083 tal = 0;
00084 if ((s = l->ql->eval(db, ctx, &tal)) != oqmlSuccess)
00085 return s;
00086
00087 al->append(tal);
00088
00089 l = next;
00090 }
00091
00092 *alist = new oqmlAtomList(makeAtomColl(al));
00093 return oqmlSuccess;
00094 }
00095
00096 void oqmlColl::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00097 {
00098 *at = eval_type;
00099 }
00100
00101 oqmlBool oqmlColl::isConstant() const
00102 {
00103 return oqml_False;
00104 }
00105
00106 std::string
00107 oqmlColl::toString(void) const
00108 {
00109 std::string s = std::string(getTypeName()) + "(";
00110
00111 if (list)
00112 {
00113 oqml_Link *l = list->first;
00114
00115 for (int n = 0; l; n++)
00116 {
00117 if (n) s += ",";
00118 s += l->ql->toString();
00119 l = l->next;
00120 }
00121 }
00122
00123 return s + ")" + oqml_isstat();
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 oqmlListColl::oqmlListColl(oqml_List * _list) : oqmlColl(_list, oqmlLISTCOLL)
00133 {
00134 eval_type.type = oqmlATOM_LIST;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 oqmlSetColl::oqmlSetColl(oqml_List * _list) : oqmlColl(_list, oqmlSETCOLL)
00144 {
00145 eval_type.type = oqmlATOM_SET;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154 oqmlBagColl::oqmlBagColl(oqml_List * _list) : oqmlColl(_list, oqmlBAGCOLL)
00155 {
00156 eval_type.type = oqmlATOM_BAG;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165 oqmlArrayColl::oqmlArrayColl(oqml_List * _list) : oqmlColl(_list, oqmlARRAYCOLL)
00166 {
00167 eval_type.type = oqmlATOM_ARRAY;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176 oqmlStruct::oqmlStruct(oqml_IdentList *_list) : oqmlNode(oqmlSTRUCT)
00177 {
00178 list = _list;
00179 }
00180
00181 oqmlStatus *oqmlStruct::compile(Database *db, oqmlContext *ctx)
00182 {
00183 oqmlStatus *s;
00184 oqml_IdentLink *l = list->first;
00185
00186 while (l)
00187 {
00188 s = l->ql->compile(db, ctx);
00189 if (s) return s;
00190 l = l->next;
00191 }
00192
00193 return oqmlSuccess;
00194 }
00195
00196 oqmlStatus *oqmlStruct::eval(Database *db, oqmlContext *ctx,
00197 oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00198 {
00199 oqmlStatus *s;
00200 oqml_StructAttr *attr = new oqml_StructAttr[list->cnt];
00201 oqml_IdentLink *l = list->first;
00202 for (int n = 0; l; n++)
00203 {
00204 oqmlAtomList *al;
00205 s = l->ql->eval(db, ctx, &al);
00206 if (s)
00207 {
00208 delete[] attr;
00209 return s;
00210 }
00211
00212 if (l->left->getType() != oqmlIDENT)
00213 {
00214 delete[] attr;
00215 return oqmlStatus::expected(this, "identifier",
00216 l->left->toString().c_str());
00217 }
00218
00219 attr[n].set(((oqmlIdent *)l->left)->getName(), al->first);
00220 l = l->next;
00221 }
00222
00223 *alist = new oqmlAtomList(new oqmlAtom_struct(attr, list->cnt));
00224 return oqmlSuccess;
00225 }
00226
00227 void oqmlStruct::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00228 {
00229 at->type = oqmlATOM_STRUCT;
00230 at->cls = 0;
00231 at->comp = oqml_False;
00232 }
00233
00234 oqmlBool oqmlStruct::isConstant() const
00235 {
00236 return oqml_False;
00237 }
00238
00239 oqmlBool
00240 oqmlStruct::hasIdent(const char *ident)
00241 {
00242 oqml_IdentLink *ln = list->first;
00243
00244 while (ln)
00245 {
00246 if (ln->ql->hasIdent(ident))
00247 return oqml_True;
00248 ln = ln->next;
00249 }
00250
00251 return oqml_False;
00252 }
00253
00254 void oqmlStruct::lock()
00255 {
00256 oqmlNode::lock();
00257 if (list) list->lock();
00258 }
00259
00260 void oqmlStruct::unlock()
00261 {
00262 oqmlNode::unlock();
00263 if (list) list->unlock();
00264 }
00265
00266 std::string
00267 oqmlStruct::toString(void) const
00268 {
00269 std::string s = "struct(";
00270
00271 oqml_IdentLink *l = list->first;
00272 for (int n = 0; l; n++)
00273 {
00274 if (n) s += ", ";
00275 s += l->left->toString() + ": " + l->ql->toString();
00276 l = l->next;
00277 }
00278
00279 return s + ")" + oqml_isstat();
00280 }
00281
00282 oqmlStruct::~oqmlStruct()
00283 {
00284 }
00285
00286
00287
00288
00289
00290
00291
00292 oqmlStructOf::oqmlStructOf(oqmlNode * _ql) : oqmlNode(oqmlSTRUCTOF)
00293 {
00294 ql = _ql;
00295 eval_type.type = oqmlATOM_STRING;
00296 eval_type.comp = oqml_True;
00297 }
00298
00299 oqmlStructOf::~oqmlStructOf()
00300 {
00301 }
00302
00303 oqmlStatus *oqmlStructOf::compile(Database *db, oqmlContext *ctx)
00304 {
00305 return ql->compile(db, ctx);
00306 }
00307
00308 oqmlStatus *oqmlStructOf::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00309 {
00310 oqmlStatus *s;
00311
00312 oqmlAtomList *al;
00313 s = ql->eval(db, ctx, &al);
00314 if (s)
00315 return s;
00316
00317 if (!al->cnt)
00318 return oqmlStatus::expected(this, "struct", "nil");
00319
00320 oqmlAtom *r = al->first;
00321 if (!OQML_IS_STRUCT(r))
00322 return oqmlStatus::expected(this, "struct", r->type.getString());
00323
00324 oqmlAtom_struct *as = r->as_struct();
00325
00326 oqmlAtomList *list = new oqmlAtomList();
00327
00328 for (int i = 0; i < as->attr_cnt; i++)
00329 list->append(new oqmlAtom_string(as->attr[i].name));
00330
00331 *alist = new oqmlAtomList(new oqmlAtom_list(list));
00332
00333 return oqmlSuccess;
00334 }
00335
00336 void oqmlStructOf::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00337 {
00338 *at = eval_type;
00339 }
00340
00341 oqmlBool oqmlStructOf::isConstant() const
00342 {
00343 return OQMLBOOL(ql->isConstant());
00344 }
00345
00346 std::string
00347 oqmlStructOf::toString(void) const
00348 {
00349 return oqml_unop_string(ql, "structof ", is_statement);
00350 }
00351
00352
00353
00354
00355
00356
00357
00358 static void
00359 oqml_flatten_realize(oqmlAtom *a, int flat, oqmlAtomList *alist)
00360 {
00361 if (a->type.type == oqmlATOM_LIST && flat) {
00362 oqmlAtom *ta = ((oqmlAtom_list *)a)->list->first;
00363 while (ta) {
00364 oqmlAtom *next = ta->next;
00365 oqml_flatten_realize(ta, flat, alist);
00366 ta = next;
00367 }
00368 }
00369 else
00370 alist->append(a);
00371 }
00372
00373 oqmlFlatten::oqmlFlatten(oqml_List * _list, int _flat) : oqmlNode(oqmlFLATTEN)
00374 {
00375 list = _list;
00376 flat = _flat;
00377 }
00378
00379 oqmlFlatten::~oqmlFlatten()
00380 {
00381 delete list;
00382 }
00383
00384 oqmlStatus *oqmlFlatten::compile(Database *db, oqmlContext *ctx)
00385 {
00386 if (!list)
00387 return oqmlSuccess;
00388
00389 oqml_Link *l = list->first;
00390
00391 oqmlBool first = oqml_True;
00392 oqmlBool do_ev_type = oqml_True;
00393
00394 while (l)
00395 {
00396 oqmlStatus *s;
00397
00398 if ((s = l->ql->compile(db, ctx)) != oqmlSuccess)
00399 return s;
00400
00401 if (do_ev_type)
00402 {
00403 oqmlAtomType at;
00404 l->ql->evalType(db, ctx, &at);
00405
00406 if (first)
00407 {
00408 first = oqml_False;
00409 eval_type = at;
00410 }
00411 else if (eval_type.type != at.type)
00412 {
00413 eval_type.type = oqmlATOM_UNKNOWN_TYPE;
00414 eval_type.cls = 0;
00415 do_ev_type = oqml_False;
00416 }
00417 }
00418
00419 l = l->next;
00420 }
00421
00422
00423 if (eval_type.type == oqmlATOM_LIST)
00424 {
00425 eval_type.type = oqmlATOM_UNKNOWN_TYPE;
00426 eval_type.cls = 0;
00427 do_ev_type = oqml_False;
00428 }
00429
00430 return oqmlSuccess;
00431 }
00432
00433 oqmlStatus *oqmlFlatten::eval(Database *db, oqmlContext *ctx,
00434 oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00435 {
00436 *alist = new oqmlAtomList();
00437
00438 if (!list)
00439 return oqmlSuccess;
00440
00441 oqmlStatus *s;
00442 oqml_Link *l = list->first;
00443
00444 while (l)
00445 {
00446 oqmlAtomList *tal;
00447 tal = 0;
00448 if ((s = l->ql->eval(db, ctx, &tal)) != oqmlSuccess)
00449 {
00450 delete tal;
00451 delete *alist;
00452 return s;
00453 }
00454
00455 oqmlAtom *a = tal->first;
00456
00457 while (a)
00458 {
00459 oqmlAtom *next = a->next;
00460 oqml_flatten_realize(a, flat, *alist);
00461 a = next;
00462 }
00463
00464 l = l->next;
00465 }
00466 return oqmlSuccess;
00467 }
00468
00469 void oqmlFlatten::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00470 {
00471 *at = eval_type;
00472 }
00473
00474 oqmlBool oqmlFlatten::isConstant() const
00475 {
00476 return oqml_False;
00477 }
00478
00479 std::string
00480 oqmlFlatten::toString(void) const
00481 {
00482 std::string s = std::string("flatten(");
00483 oqml_Link *l = list->first;
00484
00485 for (int n = 0; l; n++)
00486 {
00487 if (n) s += ",";
00488 s += l->ql->toString();
00489 l = l->next;
00490 }
00491
00492 return s + ")" + oqml_isstat();
00493 }
00494
00495 void
00496 oqmlFlatten::lock()
00497 {
00498 oqmlNode::lock();
00499 if (!list)
00500 return;
00501
00502 list->lock();
00503 }
00504
00505 void
00506 oqmlFlatten::unlock()
00507 {
00508 oqmlNode::unlock();
00509 if (!list)
00510 return;
00511
00512 list->unlock();
00513 }
00514
00515
00516
00517
00518
00519
00520
00521 oqmlStatus *oqmlCount::eval(Database *db, oqmlContext *ctx,
00522 oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00523 {
00524 oqmlStatus *s;
00525 oqmlAtomList *al;
00526
00527 s = ql->eval(db, ctx, &al);
00528
00529 if (s)
00530 return s;
00531
00532 *alist = new oqmlAtomList(new oqmlAtom_int(al->cnt));
00533
00534 return oqmlSuccess;
00535 }
00536
00537 void oqmlCount::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00538 {
00539 at->type = oqmlATOM_INT;
00540 at->cls = 0;
00541 at->comp = oqml_False;
00542 }
00543
00544 oqmlBool oqmlCount::isConstant() const
00545 {
00546 return OQMLBOOL(ql->isConstant());
00547 }
00548
00549 oqmlCount::oqmlCount(oqmlNode * _ql) : oqmlNode(oqmlCOUNT)
00550 {
00551 ql = _ql;
00552 }
00553
00554 oqmlCount::~oqmlCount()
00555 {
00556 }
00557
00558 oqmlStatus *oqmlCount::compile(Database *db, oqmlContext *ctx)
00559 {
00560 oqmlStatus *s;
00561 s = ql->compile(db, ctx);
00562
00563 if (s)
00564 return s;
00565
00566 return oqmlSuccess;
00567 }
00568
00569 std::string
00570 oqmlCount::toString(void) const
00571 {
00572 return std::string("count(") + ql->toString() + ")" + oqml_isstat();
00573 }
00574 }