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 <stdlib.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <assert.h>
00029 #include "oql_p.h"
00030
00031 #define MAX_RANGE (int)0x0A000000
00032
00033 namespace eyedb {
00034
00035 oqmlBool
00036 oqml_is_getcount(oqml_ArrayList *arr)
00037 {
00038 if (!arr)
00039 return oqml_False;
00040 return arr->is_getcount;
00041 }
00042
00043 oqmlBool
00044 oqml_is_wholecount(oqml_ArrayList *arr)
00045 {
00046 if (!arr)
00047 return oqml_False;
00048 return OQMLBOOL(arr->is_getcount && arr->is_wholecount);
00049 }
00050
00051
00052
00053
00054
00055
00056
00057 static oqmlStatus *
00058 oqml_wait_for_int(oqmlNode *node, Database *db,
00059 oqmlContext *ctx, oqmlNode *ql)
00060 {
00061 oqmlAtomType type;
00062 oqmlStatus *s;
00063
00064 if (ql->getType() != oqmlIDENT)
00065 {
00066 s = ql->compile(db, ctx);
00067 if (s)
00068 return s;
00069
00070 if (ql->isConstant())
00071 {
00072 ql->evalType(db, ctx, &type);
00073 if (type.type != oqmlATOM_INT)
00074 return oqmlStatus::expected(node, "integer", type.getString());
00075 }
00076 }
00077
00078 return oqmlSuccess;
00079 }
00080
00081
00082 static oqmlStatus *
00083 oqml_wait_for_int(oqmlNode *node, Database *db, oqmlContext *ctx,
00084 oqmlNode *ql, int *i)
00085 {
00086 oqmlStatus *s;
00087 oqmlAtomList *alist;
00088
00089 s = ql->eval(db, ctx, &alist);
00090
00091 if (s)
00092 return s;
00093
00094 if (alist->cnt != 1)
00095 return new oqmlStatus(node, "integer expected");
00096
00097 if (alist->first->type.type != oqmlATOM_INT)
00098 return oqmlStatus::expected(node, "integer",
00099 alist->first->type.getString());
00100
00101 *i = ((oqmlAtom_int *)(alist->first))->i;
00102 return oqmlSuccess;
00103 }
00104
00105 static inline int
00106 oqml_getinc(const TypeModifier *tmod, int n)
00107 {
00108 int inc = 1;
00109 for (int i = tmod->ndims-1; i > n; i--)
00110 inc *= tmod->dims[i];
00111
00112 return inc;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 struct oqmlLinkItem {
00144 int from, to;
00145 oqmlBool untilEnd;
00146 oqmlBool wholeRange;
00147 oqmlLinkItem() {
00148 from = to = 0;
00149 untilEnd = wholeRange = oqml_False;
00150 }
00151 };
00152
00153 oqml_ArrayLink::oqml_ArrayLink(oqmlBool _wholeCount)
00154 {
00155 qleft = 0;
00156 qright = 0;
00157 next = 0;
00158 wholeCount = _wholeCount;
00159 wholeRange = oqml_False;
00160 }
00161
00162 oqml_ArrayLink::oqml_ArrayLink(oqmlNode *_qleft, oqmlNode *_qright)
00163 {
00164 if (_qleft)
00165 {
00166 qleft = _qleft;
00167 qright = _qright;
00168 wholeRange = oqml_False;
00169 next = 0;
00170 return;
00171 }
00172
00173 qleft = new oqmlInt((long long)0);
00174 qright = new oqmlInt(MAX_RANGE);
00175 wholeRange = oqml_True;
00176 next = 0;
00177 }
00178
00179 oqmlBool
00180 oqml_ArrayLink::hasIdent(const char *_ident)
00181 {
00182 return OQMLBOOL((qleft && qleft->hasIdent(_ident)) ||
00183 (qright && qright->hasIdent(_ident)));
00184 }
00185
00186 oqmlBool
00187 oqml_ArrayLink::isGetCount() const
00188 {
00189 return OQMLBOOL(!qleft && !qright);
00190 }
00191
00192 std::string
00193 oqml_ArrayLink::toString() const
00194 {
00195 if (isGetCount())
00196 return wholeCount ? "[!!]" : "[!]";
00197
00198 if (wholeRange)
00199 return "[?]";
00200
00201 return std::string("[") +
00202 (qleft ? qleft->toString() : std::string("")) +
00203 (qright ? std::string(":") + qright->toString() : std::string("")) + "]";
00204 }
00205
00206 oqmlStatus *
00207 oqml_ArrayLink::compile(Database *db, oqmlContext *ctx)
00208 {
00209 oqmlStatus *s;
00210 if (qleft)
00211 {
00212 s = qleft->compile(db, ctx);
00213 if (s) return s;
00214 }
00215
00216 if (qright)
00217 return qright->compile(db, ctx);
00218 return oqmlSuccess;
00219 }
00220
00221 static oqmlStatus *
00222 oqml_eval_link(oqmlNode *node, Database *db, oqmlContext *ctx, oqmlNode *ql, int &val, oqmlBool &untilEnd)
00223 {
00224 if (ql->getType() == oqmlIDENT &&
00225 !strcmp(((oqmlIdent *)ql)->getName(), "$")) {
00226 val = MAX_RANGE;
00227 untilEnd = oqml_True;
00228 return oqmlSuccess;
00229 }
00230
00231 oqmlAtomList *al;
00232 oqmlStatus *s = ql->eval(db, ctx, &al);
00233 if (s) return s;
00234
00235 if (al->cnt == 0)
00236 return new oqmlStatus(node, "invalid right operand: "
00237 "integer expected.");
00238
00239 if (al->cnt != 1 || !al->first->as_int())
00240 return new oqmlStatus(node, "invalid right operand: "
00241 "integer expected, got '%s'.",
00242 al->first->type.getString());
00243
00244 val = OQML_ATOM_INTVAL(al->first);
00245 untilEnd = oqml_False;
00246 return oqmlSuccess;
00247 }
00248
00249 oqmlStatus *
00250 oqml_ArrayLink::eval(oqmlNode *node, Database *db, oqmlContext *ctx,
00251 oqmlLinkItem &item)
00252 {
00253 if (wholeRange) {
00254 item.from = 0;
00255 item.to = MAX_RANGE;
00256 item.wholeRange = oqml_True;
00257 return oqmlSuccess;
00258 }
00259
00260 item.wholeRange = oqml_False;
00261 oqmlStatus *s;
00262
00263 oqmlBool dummy;
00264 s = oqml_eval_link(node, db, ctx, qleft, item.from, dummy);
00265 if (s) return s;
00266
00267 if (qright)
00268 return oqml_eval_link(node, db, ctx, qright, item.to, item.untilEnd);
00269
00270 item.to = item.from;
00271 return oqmlSuccess;
00272 }
00273
00274 void
00275 oqml_ArrayLink::lock()
00276 {
00277 if (qleft) qleft->lock();
00278 if (qright) qright->lock();
00279 }
00280
00281 void
00282 oqml_ArrayLink::unlock()
00283 {
00284 if (qleft) qleft->unlock();
00285 if (qright) qright->unlock();
00286 }
00287
00288 oqml_ArrayLink::~oqml_ArrayLink()
00289 {
00290 }
00291
00292
00293
00294
00295
00296
00297
00298 oqml_ArrayList::oqml_ArrayList()
00299 {
00300 count = 0;
00301 first = last = 0;
00302 is_getcount = oqml_False;
00303 is_wholecount = oqml_False;
00304 wholeRange = oqml_True;
00305 }
00306
00307 void oqml_ArrayList::add(oqml_ArrayLink *link)
00308 {
00309 if (last)
00310 last->next = link;
00311 else
00312 first = link;
00313
00314 if (!is_getcount)
00315 {
00316 is_getcount = link->isGetCount();
00317 is_wholecount = link->wholeCount;
00318 }
00319
00320 if (!link->wholeRange)
00321 wholeRange = oqml_False;
00322
00323 last = link;
00324 count++;
00325 }
00326
00327 oqmlBool
00328 oqml_ArrayList::hasIdent(const char *_ident)
00329 {
00330 oqml_ArrayLink *l = first;
00331
00332 while (l)
00333 {
00334 if (l->hasIdent(_ident))
00335 return oqml_True;
00336 l = l->next;
00337 }
00338
00339 return oqml_False;
00340 }
00341
00342 std::string
00343 oqml_ArrayList::toString() const
00344 {
00345 oqml_ArrayLink *l = first;
00346 std::string s = "";
00347 while (l)
00348 {
00349 s += l->toString();
00350 l = l->next;
00351 }
00352
00353 return s;
00354 }
00355
00356 oqmlStatus *
00357 oqml_ArrayList::compile(Database *db, oqmlContext *ctx)
00358 {
00359 if (is_getcount)
00360 return oqmlSuccess;
00361
00362 oqmlStatus *s;
00363 oqml_ArrayLink *l = first;
00364
00365 while (l)
00366 {
00367 s = l->compile(db, ctx);
00368 if (s) return s;
00369 l = l->next;
00370 }
00371
00372 return oqmlSuccess;
00373 }
00374
00375 oqmlNode *oqmlArray::getLeft()
00376 {
00377 return ql;
00378 }
00379
00380 oqml_ArrayList *oqmlArray::getArrayList()
00381 {
00382 return list;
00383 }
00384
00385 oqmlStatus *
00386 oqml_ArrayList::eval(oqmlNode *node, Database *db, oqmlContext *ctx,
00387 oqmlLinkItem *&items, int &item_cnt)
00388 {
00389 oqmlStatus *s;
00390 oqml_ArrayLink *l = first;
00391
00392 item_cnt = count;
00393 items = new oqmlLinkItem[count];
00394
00395 for (int i = 0; l ; i++)
00396 {
00397 s = l->eval(node, db, ctx, items[i]);
00398 if (s) return s;
00399 l = l->next;
00400 }
00401
00402 return oqmlSuccess;
00403 }
00404
00405 oqmlStatus *
00406 oqml_ArrayList::checkCollArray(oqmlNode *node, const Class *cls,
00407 const char *attrname)
00408 {
00409 if (!last->wholeRange && !cls->asCollArrayClass())
00410 return new oqmlStatus(node, "non array collection invalid operator: "
00411 "'%s%s'", attrname, toString().c_str());
00412 oqml_ArrayLink *l = first;
00413 while (l != last)
00414 {
00415 if (l->qright)
00416 return new oqmlStatus(node, "collection attribute contents '%s[%s]': "
00417 "value ranges are not valid "
00418 "for intermediate dimensions",
00419 attrname, toString().c_str());
00420
00421 l = l->next;
00422 }
00423
00424 return oqmlSuccess;
00425 }
00426
00427 oqmlStatus *
00428 oqml_ArrayList::eval(oqmlNode *node, Database *db, oqmlContext *ctx,
00429 const char *clname,
00430 const char *attrname, const TypeModifier *tmod,
00431 int *s_ind, int *e_ind, oqmlBool nocheck)
00432 {
00433 *s_ind = 0;
00434 *e_ind = 0;
00435
00436 if (is_getcount)
00437 return oqmlSuccess;
00438
00439 oqmlStatus *s;
00440 int i;
00441 int n = 0;
00442 oqml_ArrayLink *l = first;
00443
00444 while (l)
00445 {
00446 int incdim = oqml_getinc(tmod, n);
00447 s = oqml_wait_for_int(node, db, ctx, l->qleft, &i);
00448
00449 if (s)
00450 return s;
00451
00452 int maxdim = (tmod && tmod->dims ? tmod->dims[n] : 0);
00453
00454 if (maxdim > 0 && i >= maxdim)
00455 {
00456 if (nocheck)
00457 i = maxdim-1;
00458 else
00459 return new oqmlStatus(node, "attribute '%s' in class '%s' : "
00460 "out of range dimension #%d: "
00461 "maximum allowed is %d <got %d>",
00462 attrname, clname,
00463 n, maxdim-1, i);
00464 }
00465
00466 *s_ind += i * incdim;
00467
00468 if (l->qright)
00469 {
00470 s = oqml_wait_for_int(node, db, ctx, l->qright, &i);
00471
00472 if (s)
00473 return s;
00474
00475 if (i == -1)
00476 {
00477 if (maxdim > 0)
00478 i = maxdim-1;
00479 else
00480 i = 10000000;
00481 }
00482 else if (maxdim > 0 && i >= maxdim)
00483 {
00484 if (nocheck)
00485 i = maxdim-1;
00486 else
00487 return new oqmlStatus(node, "attribute '%s' in class '%s' : "
00488 "out of range dimension #%d: "
00489 "maximum allowed is %d, got %d)",
00490 attrname, clname,
00491 n, maxdim, i);
00492 }
00493
00494 *e_ind += i * incdim;
00495 }
00496 else
00497 *e_ind += i * incdim;
00498
00499 l = l->next;
00500 n++;
00501 }
00502
00503 return oqmlSuccess;
00504 }
00505
00506 oqmlStatus *
00507 oqml_ArrayList::evalCollArray(oqmlNode *node, Database *db,
00508 oqmlContext *ctx,
00509 const TypeModifier *tmod, int &ind)
00510 {
00511 oqmlStatus *s;
00512 oqml_ArrayLink *l = first;
00513
00514 ind = 0;
00515
00516 for (int n = 0; l != last; n++)
00517 {
00518 int incdim = oqml_getinc(tmod, n);
00519 int i;
00520 s = oqml_wait_for_int(node, db, ctx, l->qleft, &i);
00521
00522 if (s) return s;
00523
00524 int maxdim = tmod->dims[n];
00525
00526 if (maxdim > 0 && i >= maxdim)
00527 return new oqmlStatus(node, "out of range dimension #%d: "
00528 "maximum allowed is %d, got %d",
00529 n, maxdim, i);
00530
00531 ind += i * incdim;
00532
00533 l = l->next;
00534 n++;
00535 }
00536
00537 return oqmlSuccess;
00538 }
00539
00540 void
00541 oqml_ArrayList::lock()
00542 {
00543 oqml_ArrayLink *l = first;
00544 while (l)
00545 {
00546 l->lock();
00547 l = l->next;
00548 }
00549 }
00550
00551 void
00552 oqml_ArrayList::unlock()
00553 {
00554 oqml_ArrayLink *l = first;
00555 while (l)
00556 {
00557 l->unlock();
00558 l = l->next;
00559 }
00560 }
00561
00562 oqml_ArrayList::~oqml_ArrayList()
00563 {
00564 oqml_ArrayLink *l = first;
00565 while (l)
00566 {
00567 oqml_ArrayLink *next = l->next;
00568 delete l;
00569 l = next;
00570 }
00571 }
00572
00573
00574
00575
00576
00577
00578
00579 oqmlArray::oqmlArray(oqmlNode * _ql) : oqmlNode(oqmlARRAY)
00580 {
00581 ql = _ql;
00582 list = new oqml_ArrayList();
00583 delegationArray = oqml_False;
00584 returnStruct = oqml_True;
00585 }
00586
00587 oqmlArray::oqmlArray(oqmlNode * _ql, oqml_ArrayList *_list,
00588 oqmlBool _returnStruct) : oqmlNode(oqmlARRAY)
00589 {
00590 ql = _ql;
00591 list = _list;
00592 delegationArray = oqml_True;
00593 returnStruct = _returnStruct;
00594 }
00595
00596 oqmlStatus *
00597 oqmlArray::evalMake(Database *db, oqmlContext *ctx, Object *o,
00598 oqml_ArrayList *list, oqmlBool returnStruct, oqmlAtomList **alist)
00599 {
00600 oqmlArray *array = new oqmlArray(new oqmlObject(o, 0), list,
00601 returnStruct);
00602 oqmlStatus *s = array->compile(db, ctx);
00603 if (s) return s;
00604 return array->eval(db, ctx, alist);
00605 }
00606
00607 oqmlArray::~oqmlArray()
00608 {
00609 if (!delegationArray)
00610 delete list;
00611 }
00612
00613 void oqmlArray::add(oqml_ArrayLink *link)
00614 {
00615 list->add(link);
00616 }
00617
00618 oqmlStatus *oqmlArray::compile(Database *db, oqmlContext *ctx)
00619 {
00620 oqmlDotContext *dctx = ctx->getDotContext();
00621 oqmlStatus *s;
00622
00623 if (!dctx)
00624 {
00625 s = ql->compile(db, ctx);
00626 if (s) return s;
00627 return list->compile(db, ctx);
00628 }
00629
00630 if (ql->getType() == oqmlIDENT)
00631 {
00632 const char *name = ((oqmlIdent *)ql)->getName();
00633 oqmlDotDesc *desc = &dctx->desc[dctx->count-1];
00634
00635 Class *cls = (Class *)desc->cls;
00636
00637 Attribute *attr = (Attribute *)desc->attr;
00638 if (cls)
00639 {
00640 attr = (Attribute *)cls->getAttribute(name);
00641
00642 if (!attr)
00643 return new oqmlStatus(this, "attribute '%s' not "
00644 "found in class '%s'", name, cls->getName());
00645 }
00646
00647 if (!list->is_getcount)
00648 {
00649 oqml_ArrayLink *l = list->first;
00650
00651 while (l)
00652 {
00653 s = oqml_wait_for_int(this, db, ctx, l->qleft);
00654
00655 if (s)
00656 return s;
00657
00658 if (l->qright)
00659 {
00660 s = oqml_wait_for_int(this, db, ctx, l->qright);
00661
00662 if (s)
00663 return s;
00664 }
00665
00666 l = l->next;
00667 }
00668 }
00669
00670 s = dctx->add(db, ctx, attr, list, (char *)name, 0, 0, 0);
00671 if (s)
00672 return s;
00673 eval_type = dctx->dot_type;
00674 return oqmlSuccess;
00675 }
00676
00677 return new oqmlStatus(this, "currently cannot deal with no ident left "
00678 "part in array");
00679 }
00680
00681 #define MAKELEFTVALUE(X) \
00682 do { \
00683 if (ridx) \
00684 { \
00685 if (dim == item_cnt - 1) \
00686 { \
00687 if (n != 0) \
00688 { \
00689 delete[] items; \
00690 return new oqmlStatus(this, "invalid left value."); \
00691 } \
00692 *ridx = idx; \
00693 *ra = x; \
00694 } \
00695 else \
00696 xlist->append(X); \
00697 } \
00698 else \
00699 xlist->append(X); \
00700 } while(0)
00701
00702 oqmlStatus *
00703 oqmlArray::checkRange(oqmlLinkItem *items, int dim, int idx, int len,
00704 oqmlBool &stop, const char *msg)
00705 {
00706 if (idx >= len && items[dim].untilEnd)
00707 {
00708 stop = oqml_True;
00709 return oqmlSuccess;
00710 }
00711
00712 if (idx < 0 || idx >= len)
00713 {
00714 if (!items[dim].wholeRange)
00715 {
00716 delete[] items;
00717 return new oqmlStatus(this, "out of bounds "
00718 "value, %d, for %s", idx, msg);
00719 }
00720 stop = oqml_True;
00721 return oqmlSuccess;
00722 }
00723
00724 stop = oqml_False;
00725 return oqmlSuccess;
00726 }
00727
00728 oqmlStatus *
00729 oqmlArray::evalRealize_1(Database *db, oqmlContext *ctx,
00730 oqmlAtom *x, oqmlAtomList **alist, oqmlAtom **ra,
00731 int *ridx)
00732 {
00733 static const char fmt[] = "invalid operand, "
00734 "string, collection or struct.";
00735
00736 if (ridx)
00737 return new oqmlStatus(this, "invalid left operand");
00738
00739 if (!x->as_string() && !x->as_coll() && !x->as_struct())
00740 return new oqmlStatus(this, fmt);
00741
00742 if (x->as_string())
00743 {
00744 if (alist)
00745 *alist =
00746 new oqmlAtomList(new oqmlAtom_int(OQML_ATOM_STRLEN(x)));
00747 return oqmlSuccess;
00748 }
00749
00750 if (x->as_coll())
00751 {
00752 if (alist)
00753 *alist =
00754 new oqmlAtomList(new oqmlAtom_int(OQML_ATOM_COLLVAL(x)->cnt));
00755 return oqmlSuccess;
00756 }
00757
00758 if (x->as_struct())
00759 {
00760 if (alist)
00761 *alist =
00762 new oqmlAtomList(new oqmlAtom_int(x->as_struct()->attr_cnt));
00763 return oqmlSuccess;
00764 }
00765
00766 return new oqmlStatus(this, fmt);
00767 }
00768
00769
00770 oqmlStatus *oqmlArray::evalRealize_2(Database *db, oqmlContext *ctx,
00771 oqmlAtom *x, oqmlAtomList **alist,
00772 oqmlAtom **ra, int *ridx)
00773 {
00774 static const char fmt[] = "invalid%soperand, "
00775 "string, list, array or struct.";
00776
00777 oqmlLinkItem *items = 0;
00778 int item_cnt;
00779 oqmlStatus *s;
00780
00781 s = list->eval(this, db, ctx, items, item_cnt);
00782
00783 if (s) return s;
00784
00785 if (ridx) {
00786 *ridx = -1;
00787 *ra = 0;
00788 }
00789
00790 if (!x->as_string() && !x->as_list() && !x->as_array() &&
00791 !x->as_struct() && !OQML_IS_OBJECT(x))
00792 return new oqmlStatus(this, fmt, ridx ? " left " : " ");
00793
00794 for (int dim = 0; dim < item_cnt; dim++) {
00795 oqmlAtomList *xlist = new oqmlAtomList();
00796 oqmlBool stop;
00797
00798 if (!x)
00799 break;
00800
00801 if (x->as_string()) {
00802 const char *str = OQML_ATOM_STRVAL(x);
00803 int len = OQML_ATOM_STRLEN(x) + (ridx ? 0 : 1);
00804 for (int idx = items[dim].from, n = 0; idx <= items[dim].to; idx++,
00805 n++) {
00806
00807
00808
00809
00810
00811 s = checkRange(items, dim, idx, len, stop,
00812
00813 str);
00814 if (s) return s;
00815 if (stop) break;
00816
00817 MAKELEFTVALUE(new oqmlAtom_char(str[idx]));
00818 }
00819 }
00820 else if (x->as_list() || x->as_array()) {
00821 oqmlAtomList *alist = OQML_ATOM_COLLVAL(x);
00822 for (int idx = items[dim].from, n = 0; idx <= items[dim].to; idx++,
00823 n++) {
00824 s = checkRange(items, dim, idx, alist->cnt, stop, "list");
00825 if (s) return s;
00826 if (stop) break;
00827
00828 MAKELEFTVALUE(alist->getAtom(idx)->copy());
00829 }
00830 }
00831 else if (x->as_struct()) {
00832 oqmlAtom_struct *astruct = x->as_struct();
00833 for (int idx = items[dim].from, n = 0; idx <= items[dim].to; idx++,
00834 n++) {
00835 s = checkRange(items, dim, idx, astruct->attr_cnt, stop, "struct");
00836 if (s) return s;
00837 if (stop) break;
00838
00839 MAKELEFTVALUE(astruct->attr[idx].value->copy());
00840 }
00841 }
00842 else if (OQML_IS_OBJECT(x)) {
00843 OQL_CHECK_OBJ(x);
00844 Object *o = 0;
00845 s = oqmlObjectManager::getObject(this, db, x, o, oqml_True,
00846 oqml_True);
00847 if (s) return s;
00848 if (!o->asCollArray())
00849 return new oqmlStatus(this, "only support array collection");
00850
00851 Bool is_ref;
00852 (void)o->getClass()->asCollectionClass()->getCollClass(&is_ref);
00853 if (!is_ref)
00854 return new oqmlStatus(this, "only support collection array of "
00855 "objects");
00856 if (ridx) {
00857 if (items[dim].from != items[dim].to)
00858 return new oqmlStatus(this, "invalid left value");
00859 int n = 0;
00860 int idx = items[dim].from;
00861 if (OQML_IS_OBJ(x))
00862 MAKELEFTVALUE(new oqmlAtom_oid(OQML_ATOM_OBJVAL(x)->getOid()));
00863 else
00864 MAKELEFTVALUE(x->copy());
00865 continue;
00866 }
00867
00868 Status is = Success;
00869 for (int idx = items[dim].from, n = 0; idx <= items[dim].to; idx++,
00870 n++) {
00871 if (n >= o->asCollArray()->getTop())
00872 break;
00873 if (dim == item_cnt - 1) {
00874 Oid obj_oid;
00875 is = o->asCollArray()->retrieveAt(idx, obj_oid);
00876 if (is) break;
00877
00878 if (returnStruct && items[dim].from != items[dim].to)
00879 xlist->append(oqml_make_struct_array(db, ctx, idx, new oqmlAtom_oid(obj_oid)));
00880 else
00881 xlist->append(new oqmlAtom_oid(obj_oid));
00882 }
00883 else {
00884 xlist->append(oqmlObjectManager::registerObject(o));
00885 }
00886 }
00887
00888 if (is) return new oqmlStatus(this, is);
00889 }
00890 else {
00891 delete[] items;
00892 return new oqmlStatus(this, fmt, ridx ? " left " : " ");
00893 }
00894
00895 if (xlist->cnt > 1) {
00896 if (x->as_array())
00897 x = new oqmlAtom_array(xlist);
00898 else
00899 x = new oqmlAtom_list(xlist);
00900 }
00901 else
00902 x = xlist->first;
00903 }
00904
00905 if (alist)
00906 *alist = new oqmlAtomList(x);
00907
00908 delete[] items;
00909 return oqmlSuccess;
00910 }
00911
00912
00913 oqmlStatus *oqmlArray::evalRealize(Database *db, oqmlContext *ctx,
00914 oqmlAtomList **alist, oqmlAtom **ra,
00915 int *ridx)
00916 {
00917 oqmlStatus *s;
00918
00919 oqmlAtomList *alleft;
00920 s = ql->eval(db, ctx, &alleft);
00921
00922 if (s)
00923 return s;
00924
00925 if (alleft->cnt != 1)
00926 return new oqmlStatus(this, "invalid left operand.");
00927
00928 oqmlAtom *x = alleft->first;
00929 if (list->is_getcount)
00930 {
00931 if (list->is_wholecount)
00932 return new oqmlStatus(this, "invalid operand");
00933 return evalRealize_1(db, ctx, x, alist, ra, ridx);
00934 }
00935
00936 return evalRealize_2(db, ctx, x, alist, ra, ridx);
00937 }
00938
00939 oqmlStatus *oqmlArray::eval(Database *db, oqmlContext *ctx,
00940 oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00941 {
00942 return evalRealize(db, ctx, alist, 0, 0);
00943 }
00944
00945 oqmlStatus *oqmlArray::evalLeft(Database *db, oqmlContext *ctx,
00946 oqmlAtom **ra, int &ridx)
00947 {
00948 return evalRealize(db, ctx, 0, ra, &ridx);
00949 }
00950
00951 void oqmlArray::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00952 {
00953 *at = eval_type;
00954 }
00955
00956 oqmlBool oqmlArray::isConstant() const
00957 {
00958 return oqml_False;
00959 }
00960
00961 oqmlBool
00962 oqmlArray::hasIdent(const char *_ident)
00963 {
00964 return OQMLBOOL(((ql && ql->hasIdent(_ident)) ||
00965 (list && list->hasIdent(_ident))));
00966 }
00967
00968 std::string
00969 oqmlArray::toString(void) const
00970 {
00971 return ql->toString() + list->toString();
00972 }
00973
00974 void
00975 oqmlArray::lock()
00976 {
00977 oqmlNode::lock();
00978 ql->lock();
00979 list->lock();
00980 }
00981
00982 void
00983 oqmlArray::unlock()
00984 {
00985 oqmlNode::unlock();
00986 ql->unlock();
00987 list->unlock();
00988 }
00989 }