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 <eyedb/oqlctb.h>
00030
00031 #include "oql_p.h"
00032
00033
00034
00035
00036
00037
00038
00039 namespace eyedb {
00040
00041 static oqmlStatus *
00042 oqmlGetValidAtomType(oqmlNode *node, const Attribute *attr,
00043 int ndims, oqmlAtomType &at)
00044 {
00045 const Class *cls = attr->getClass();
00046 int attr_ndims = attr->getTypeModifier().ndims;
00047 const char *name = cls->getName();
00048
00049 int mode = attr_ndims - ndims;
00050
00051 if (mode < 0)
00052 return new oqmlStatus(node, "invalid assignation for attribute '%s': to many array specifiers", attr->getName());
00053
00054 if (mode > 1)
00055 return new oqmlStatus(node, "invalid assignation for attribute '%s': not enough array specifiers", attr->getName());
00056
00057 if (attr->isIndirect()) {
00058 at.type = oqmlATOM_OID;
00059 at.comp = oqml_False;
00060 }
00061 else if ((!strcmp(name, char_class_name) || !strcmp(name, "byte")) &&
00062 mode) {
00063 at.type = oqmlATOM_STRING;
00064 at.comp = oqml_True;
00065 }
00066 else {
00067 if (cls->asInt32Class() || cls->asInt16Class() || cls->asInt64Class())
00068 at.type = oqmlATOM_INT;
00069 else if (!strcmp(name, char_class_name) || !strcmp(name, "byte"))
00070 at.type = oqmlATOM_CHAR;
00071 else if (!strcmp(name, "float") || !strcmp(name, "double"))
00072 at.type = oqmlATOM_DOUBLE;
00073 else if (!strcmp(name, "oid"))
00074 at.type = oqmlATOM_OID;
00075 else if (cls->asEnumClass())
00076 at.type = oqmlATOM_INT;
00077 else
00078 at.type = oqmlATOM_OBJ;
00079 at.comp = oqml_False;
00080 }
00081
00082
00083
00084
00085
00086 return oqmlSuccess;
00087 }
00088
00089 static oqmlStatus *
00090 oqmlCheckType(oqmlNode *node, Database *db,
00091 const Attribute *attr,
00092 const oqmlAtomType *at, int ndims)
00093 {
00094 if (at->type == oqmlATOM_UNKNOWN_TYPE)
00095 return oqmlSuccess;
00096
00097 oqmlAtomType vat;
00098 oqmlStatus *s;
00099 s = oqmlGetValidAtomType(node, attr, ndims, vat);
00100
00101 if (s)
00102 return s;
00103
00104 if (vat.type == at->type)
00105 return oqmlSuccess;
00106
00107
00108
00109
00110
00111
00112
00113
00114 return oqmlStatus::expected(node, &vat, (oqmlAtomType *)at);
00115 }
00116
00117
00118
00119
00120
00121
00122
00123 oqmlNew::oqmlNew(oqmlNode *_location, const char *_ident,
00124 oqml_IdentList * _ident_list) : oqmlNode(oqmlNEW)
00125 {
00126 location = _location;
00127 ident = strdup(_ident);
00128 ident_list = _ident_list;
00129 ql = 0;
00130 comp = 0;
00131 if (!location)
00132 eval_type.type = oqmlATOM_OBJ;
00133 else
00134 eval_type.type = oqmlATOM_OID;
00135 quoted_odl = 0;
00136 }
00137
00138 oqmlNew::oqmlNew(oqmlNode *_location, const char *_ident, oqmlNode *_ql) :
00139 oqmlNode(oqmlNEW)
00140 {
00141 location = _location;
00142 ident = strdup(_ident);
00143 ident_list = 0;
00144 ql = _ql;
00145 comp = 0;
00146 eval_type.type = oqmlATOM_OID;
00147 cst_atom = 0;
00148 quoted_odl = 0;
00149 }
00150
00151 oqmlNew::oqmlNew(oqmlNode *_location, const char *_quoted_odl) :
00152 oqmlNode(oqmlNEW)
00153 {
00154 location = _location;
00155 ident = 0;
00156 ident_list = 0;
00157 ql = 0;
00158 comp = 0;
00159 eval_type.type = oqmlATOM_LIST;
00160 cst_atom = 0;
00161 quoted_odl = strdup(_quoted_odl);
00162 }
00163
00164 void
00165 oqmlNew::lock()
00166 {
00167 oqmlNode::lock();
00168 if (location)
00169 location->lock();
00170 if (ident_list)
00171 ident_list->lock();
00172 }
00173
00174 void
00175 oqmlNew::unlock()
00176 {
00177 oqmlNode::unlock();
00178 if (location)
00179 location->unlock();
00180 if (ident_list)
00181 ident_list->unlock();
00182 }
00183
00184 oqmlNew::~oqmlNew()
00185 {
00186 free(ident);
00187 free(quoted_odl);
00188 delete ident_list;
00189 delete comp;
00190 }
00191
00192 #define IS_NUM(AT) ((AT).type == oqmlATOM_DOUBLE || \
00193 (AT).type == oqmlATOM_INT || \
00194 (AT).type == oqmlATOM_CHAR)
00195 oqmlStatus *
00196 oqmlNew::compileNode(Database *db, oqmlContext *ctx, const Class *cls)
00197 {
00198 if (!cls->asBasicClass() && !cls->asEnumClass())
00199 return new oqmlStatus(this, "class '%s' is not a basic class", ident);
00200
00201 _class = (Class *)cls;
00202 if (cls->asEnumClass())
00203 {
00204 if (ql->getType() == oqmlIDENT)
00205 {
00206 const char *name = ((oqmlIdent *)ql)->getName();
00207 const EnumItem *en = cls->asEnumClass()->
00208 getEnumItemFromName(name);
00209
00210 if (!en)
00211 return new oqmlStatus(this,
00212 "unknown value '%s' for enum class '%s'",
00213 name, ident);
00214 cst_atom = new oqmlAtom_int(en->getValue());
00215 }
00216 }
00217
00218 oqmlStatus *s = ql->compile(db, ctx);
00219 if (s) return s;
00220
00221 oqmlAtomType at;
00222 ql->evalType(db, ctx, &at);
00223
00224 if (at.type == oqmlATOM_UNKNOWN_TYPE)
00225 return oqmlSuccess;
00226
00227 #if 0
00228 if (cls->asFloatClass())
00229 {
00230 if (!IS_NUM(at))
00231 return oqmlStatus::expected(this, "float", at.getString());
00232 }
00233 else if (cls->asByteClass() || cls->asCharClass())
00234 {
00235 if (!IS_NUM(at))
00236 return oqmlStatus::expected(this, "char", at.getString());
00237 }
00238 else if (cls->asInt32Class() || cls->asInt64Class() || cls->asInt16Class())
00239 {
00240 if (!IS_NUM(at))
00241 return oqmlStatus::expected(this, "integer", at.getString());
00242 }
00243 else if (cls->asOidClass())
00244 {
00245 if (at.type != oqmlATOM_OID)
00246 return oqmlStatus::expected(this, "oid", at.getString());
00247 }
00248 else
00249 return new oqmlStatus(this, "class '%s' not supported", cls->getName());
00250 #endif
00251
00252 if (ql->isConstant())
00253 {
00254 oqmlAtomList *al;
00255 s = ql->eval(db, ctx, &al);
00256 if (s)
00257 return s;
00258 if (al->cnt != 1)
00259 return new oqmlStatus(this, "constant expected");
00260 cst_atom = al->first->copy();
00261 }
00262
00263 return oqmlSuccess;
00264 }
00265
00266 oqmlStatus *
00267 oqmlNew::compileIdent(Database *db, oqmlContext *ctx, const Class *cls,
00268 oqmlNode *left, int n, int &ndims)
00269 {
00270 comp->attr[n] = (Attribute *)cls->getAttribute
00271 ( ((oqmlIdent *)left)->getName() );
00272 if (!comp->attr[n])
00273 return new oqmlStatus(this, "cannot find attribute '%s' in class '%s'",
00274 ((oqmlIdent *)left)->getName(),
00275 cls->getName());
00276 comp->attrname[n] = strdup(((oqmlIdent *)left)->getName());
00277 return oqmlSuccess;
00278 }
00279
00280 oqmlStatus *
00281 oqmlNew::compileDot(Database *db, oqmlContext *ctx, const Class *cls,
00282 oqmlNode *left, int n, int &ndims)
00283 {
00284 if (ctx->getDotContext())
00285 return new oqmlStatus(this, "internal error #110");
00286
00287 comp->dot_ctx[n] = new oqmlDotContext(0, cls);
00288 oqmlDotContext *dot_ctx = comp->dot_ctx[n];
00289
00290 ctx->setDotContext(dot_ctx);
00291
00292 oqmlStatus *s = left->compile(db, ctx);
00293 if (s) return s;
00294
00295 s = left->asDot()->check(db, dot_ctx);
00296 if (s) return s;
00297
00298 ctx->setDotContext(0);
00299 oqmlDotDesc *d = &dot_ctx->desc[dot_ctx->count - 1];
00300
00301 comp->attr[n] = (Attribute *)d->attr;
00302
00303 if (!comp->attr[n])
00304 return new oqmlStatus(this, "internal error #111");
00305
00306 comp->attrname[n] = strdup(d->attrname);
00307 ndims = (d->array ? d->array->count : 0);
00308 return oqmlSuccess;
00309 }
00310
00311 oqmlStatus *
00312 oqmlNew::compileArray(Database *db, oqmlContext *ctx,
00313 const Class *cls, oqmlNode *left, int n, int &ndims)
00314 {
00315 comp->dot_ctx[n] = new oqmlDotContext(0, cls);
00316
00317 oqmlArray *array = (oqmlArray *)left;
00318 oqmlNode *xident = array->getLeft();
00319
00320 if (xident->getType() != oqmlIDENT)
00321 return new oqmlStatus(this, "left part of array is not an ident");
00322
00323 comp->attr[n] = (Attribute *)
00324 cls->getAttribute
00325 (((oqmlIdent *)xident)->getName() );
00326
00327 if (!comp->attr[n])
00328 return new oqmlStatus(this, "compilation array error in new operator");
00329
00330 comp->attrname[n] = strdup(((oqmlIdent *)xident)->getName());
00331 comp->list[n] = array->getArrayList();
00332 ndims = comp->list[n]->count;
00333 return oqmlSuccess;
00334 }
00335
00336 oqmlStatus *oqmlNew::compile(Database *db, oqmlContext *ctx)
00337 {
00338 oqmlStatus *s = oqml_get_location(db, ctx, location);
00339 if (s) return s;
00340 newdb = db;
00341
00342 if (!db->isInTransaction())
00343 return new oqmlStatus(this, "must be done within the scope of "
00344 "a transaction in database '%s'", db->getName());
00345
00346 Class *cls;
00347
00348 cls = db->getSchema()->getClass(ident);
00349
00350 if (!cls)
00351 return new oqmlStatus(this, "invalid class '%s'", ident);
00352
00353 if (ql)
00354 return compileNode(db, ctx, cls);
00355
00356 comp = new newCompile(cls, (ident_list ? ident_list->cnt : 0));
00357
00358 oqml_IdentLink *l = (ident_list ? ident_list->first : 0);
00359
00360 if (!location)
00361 eval_type.type = oqmlATOM_OBJ;
00362 else
00363 eval_type.type = oqmlATOM_OID;
00364
00365 eval_type.cls = cls;
00366
00367 int n = 0;
00368
00369 while (l)
00370 {
00371 oqmlNode *left = l->left;
00372 oqmlTYPE xtype = left->getType();
00373 int ndims = 0;
00374
00375 if (xtype == oqmlIDENT)
00376 {
00377 s = compileIdent(db, ctx, cls, left, n, ndims);
00378 if (s) return s;
00379 }
00380 else if (xtype == oqmlDOT)
00381 {
00382 s = compileDot(db, ctx, cls, left, n, ndims);
00383 if (s) return s;
00384 }
00385 else if (xtype == oqmlARRAY)
00386 {
00387 s = compileArray(db, ctx, cls, left, n, ndims);
00388 if (s) return s;
00389 }
00390 else
00391 return new oqmlStatus(this, "left part is not a left value");
00392
00393 s = l->ql->compile(db, ctx);
00394 if (s)
00395 return s;
00396
00397 oqmlAtomType at;
00398 l->ql->evalType(db, ctx, &at);
00399
00400 if (s = oqmlCheckType(this, db, comp->attr[n], &at, ndims))
00401 return s;
00402
00403 l = l->next;
00404 n++;
00405 }
00406
00407 return oqmlSuccess;
00408 }
00409
00410 oqmlStatus *
00411 oqmlNew::makeAtom(Database *db, oqmlContext *ctx, Object *o,
00412 oqmlAtom *&r)
00413 {
00414 if (!location)
00415 {
00416 r = oqmlObjectManager::registerObject(o);
00417 return oqmlSuccess;
00418 }
00419
00420 o->setDatabase(db);
00421 Status is = o->realize();
00422 if (is)
00423 {
00424 o->release();
00425 return new oqmlStatus(this, is);
00426 }
00427
00428 r = new oqmlAtom_oid(o->getOid());
00429 o->release();
00430 return oqmlSuccess;
00431 }
00432
00433 #define oqmlDEF_GET_NUM(TYP1, TYP2) \
00434 oqmlStatus * \
00435 get##TYP1##Val(oqmlNode *node, oqmlAtom *x, unsigned char buff[]) \
00436 { \
00437 TYP2 i; \
00438 if (x->as_int()) \
00439 i = OQML_ATOM_INTVAL(x); \
00440 else if (x->as_double()) \
00441 i = OQML_ATOM_DBLVAL(x); \
00442 else if (x->as_char()) \
00443 i = OQML_ATOM_CHARVAL(x); \
00444 else \
00445 return new oqmlStatus(node, "unexpected '%s' atom type", \
00446 x->type.getString()); \
00447 mcp(buff, &i, sizeof(i)); \
00448 return oqmlSuccess;\
00449 }
00450
00451 #define oqmlGET_VAL(TYP) \
00452 (_class->as##TYP##Class()) \
00453 { \
00454 s = get##TYP##Val(this, atom, buff); \
00455 if (s) return s; \
00456 }
00457
00458 oqmlDEF_GET_NUM(Int32, eyedblib::int32)
00459 oqmlDEF_GET_NUM(Int64, eyedblib::int64)
00460 oqmlDEF_GET_NUM(Int16, eyedblib::int16)
00461 oqmlDEF_GET_NUM(Char, char)
00462 oqmlDEF_GET_NUM(Byte, char)
00463 oqmlDEF_GET_NUM(Float, double)
00464
00465 oqmlStatus *
00466 getOidVal(oqmlNode *node, oqmlAtom *x, unsigned char buff[])
00467 {
00468 if (!x->as_oid())
00469 return new oqmlStatus(node, "unexpected '%s' atom type",
00470 x->type.getString());
00471
00472 mcp(buff, &OQML_ATOM_OIDVAL(x), sizeof(Oid));
00473 return oqmlSuccess;
00474 }
00475
00476 oqmlStatus *oqmlNew::evalNode(Database *db, oqmlContext *ctx,
00477 oqmlAtomList **alist)
00478 {
00479 oqmlAtom *atom;
00480 oqmlStatus *s;
00481 oqmlAtom *r;
00482
00483 if (cst_atom)
00484 atom = cst_atom;
00485 else
00486 {
00487 oqmlAtomList *al;
00488 s = ql->eval(db, ctx, &al);
00489 if (s)
00490 return s;
00491 if (al->cnt != 1)
00492 return new oqmlStatus(this, "constant expected");
00493 atom = al->first->copy();
00494 }
00495
00496 Object *o = _class->newObj();
00497
00498 unsigned char buff[32];
00499
00500 if oqmlGET_VAL(Int32)
00501 else if oqmlGET_VAL(Int64)
00502 else if oqmlGET_VAL(Int16)
00503 else if oqmlGET_VAL(Float)
00504 else if oqmlGET_VAL(Char)
00505 else if oqmlGET_VAL(Byte)
00506 else if oqmlGET_VAL(Oid)
00507 else
00508 return new oqmlStatus(this, "class '%s' not supported", _class->getName());
00509
00510 Status is = o->setValue(buff);
00511 if (is)
00512 {
00513 o->release();
00514 return new oqmlStatus(this, is);
00515 }
00516
00517 s = makeAtom(db, ctx, o, r);
00518 if (s) return s;
00519 (*alist)->append(r);
00520
00521 return oqmlSuccess;
00522 }
00523
00524 oqmlStatus *
00525 oqmlNew::evalItem(Database *db, oqmlContext *ctx,
00526 Agregat *o, oqml_IdentLink *l, int n,
00527 oqmlBool &stop, oqmlAtomList **alist)
00528 {
00529 oqmlAtomList *at;
00530 oqmlStatus *s = l->ql->eval(db, ctx, &at);
00531 oqmlTYPE xtype = l->left->getType();
00532
00533 if (s)
00534 {
00535 o->release();
00536 return s;
00537 }
00538
00539 stop = oqml_False;
00540 oqmlAtom *value = at->first;
00541
00542 if (xtype == oqmlDOT)
00543 {
00544 oqmlAtomList *dummy = new oqmlAtomList;
00545 s = comp->dot_ctx[n]->eval_perform(db, ctx, o, value, 1, &dummy);
00546 if (s)
00547 {
00548 o->release();
00549 return s;
00550 }
00551 return oqmlSuccess;
00552 }
00553
00554 Data val;
00555 unsigned char data[16];
00556 Size size;
00557 int len;
00558 Bool isIndirect = (comp->attr[n]->isIndirect());
00559
00560 size = sizeof(data);
00561 if (value && value->getData(data, &val, size, len,
00562 comp->attr[n]->getClass()))
00563 {
00564 int nb, s_ind, e_ind;
00565
00566 if (xtype == oqmlIDENT)
00567 {
00568 s_ind = e_ind = 0;
00569 nb = len;
00570 }
00571 else if (xtype == oqmlARRAY)
00572 {
00573 ctx->setDotContext(comp->dot_ctx[n]);
00574 oqml_ArrayList *list = ((oqmlArray *)l->left)->
00575 getArrayList();
00576 s = list->eval(this, db, ctx,
00577 comp->attr[n]->getClassOwner()->getName(),
00578 comp->attr[n]->getName(),
00579 &comp->attr[n]->getTypeModifier(),
00580 &s_ind, &e_ind, oqml_False);
00581 if (s)
00582 {
00583 o->release();
00584 return s;
00585 }
00586 nb = 1;
00587 ctx->setDotContext(0);
00588 }
00589 else
00590 assert(0);
00591
00592 nb = len;
00593
00594
00595
00596 s = oqmlCheckType(this, db, comp->attr[n], &value->type, 0);
00597 if (s) return s;
00598
00599 Status is;
00600
00601 oqmlBool enough;
00602 if (isIndirect) {
00603 int tnb = e_ind - s_ind + 1;
00604 is = oqml_check_vardim(comp->attr[n], o, OQMLBOOL(value),
00605 enough,
00606 s_ind, tnb,
00607 comp->attr[n]->getTypeModifier().pdims,
00608 OQMLCOMPLETE(value));
00609 }
00610 else
00611 is = oqml_check_vardim(comp->attr[n], o, OQMLBOOL(value),
00612 enough,
00613 s_ind, nb,
00614 comp->attr[n]->getTypeModifier().pdims,
00615 OQMLCOMPLETE(value));
00616
00617 if (is)
00618 {
00619 o->release();
00620 return new oqmlStatus(this, is);
00621 }
00622
00623 if (!enough)
00624 {
00625 if (value)
00626 return oqmlSuccess;
00627 else
00628 {
00629 stop = oqml_True;
00630 return oqmlSuccess;
00631 }
00632 }
00633
00634 for (int ind = s_ind; ind <= e_ind; ind++)
00635 {
00636 OQML_CHECK_INTR();
00637 Status status;
00638 if (isIndirect)
00639 status = o->setItemOid(comp->attr[n], (Oid *)data,
00640 1, ind);
00641 else
00642 status = o->setItemValue(comp->attr[n], (val ? val : data),
00643 nb, ind);
00644 if (status)
00645 {
00646 o->release();
00647 return new oqmlStatus(this, status);
00648 }
00649 }
00650 return oqmlSuccess;
00651 }
00652
00653 o->release();
00654 return new oqmlStatus(this, "error null data");
00655 }
00656
00657 static Agregat *
00658 make_new_obj(Database *db, Class *cls)
00659 {
00660
00661
00662
00663
00664 const char *name = cls->getName();
00665 char c = name[0];
00666
00667 if (c == 'c')
00668 {
00669 if (!strcmp(name, "connection"))
00670 return new OqlCtbConnection(db);
00671 }
00672 else if (c == 'd')
00673 {
00674 if (!strcmp(name, "database"))
00675 return new OqlCtbDatabase(db);
00676 }
00677
00678
00679 Database::consapp_t consapp = db->getConsApp(cls);
00680 if (consapp)
00681 return (Agregat *)consapp(cls, 0);
00682
00683 return (Agregat*)cls->newObj();
00684 }
00685
00686 oqmlStatus *oqmlNew::eval(Database *db, oqmlContext *ctx,
00687 oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00688 {
00689 oqmlStatus *s;
00690 db = newdb;
00691
00692 *alist = new oqmlAtomList();
00693
00694
00695 db = newdb;
00696
00697 if (ql)
00698 return evalNode(db, ctx, alist);
00699
00700 oqml_IdentLink *l = (ident_list ? ident_list->first : 0);
00701
00702 Agregat *o = make_new_obj(db, comp->cls);
00703
00704 if (!o)
00705 {
00706 (*alist)->append(new oqmlAtom_null());
00707 return oqmlSuccess;
00708 }
00709
00710 Status status = o->setDatabase(db);
00711 if (status)
00712 {
00713 o->release();
00714 return new oqmlStatus(this, status);
00715 }
00716
00717 int n = 0;
00718
00719 while (l)
00720 {
00721 oqmlBool stop;
00722 s = evalItem(db, ctx, o, l, n, stop, alist);
00723 if (s) return s;
00724 if (stop) break;
00725
00726 l = l->next;
00727 n++;
00728 }
00729
00730 oqmlAtom *r;
00731 s = makeAtom(db, ctx, o, r);
00732 if (s) return s;
00733 (*alist)->append(r);
00734 return oqmlSuccess;
00735 }
00736
00737 void oqmlNew::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00738 {
00739 *at = eval_type;
00740 }
00741
00742 oqmlBool oqmlNew::isConstant() const
00743 {
00744 return oqml_False;
00745 }
00746
00747 std::string
00748 oqmlNew::toString(void) const
00749 {
00750 std::string s = std::string("new") +
00751 (location ? std::string("<") + location->toString() + "> " : std::string(" ")) +
00752 ident + "(";
00753
00754 if (ident_list)
00755 {
00756 oqml_IdentLink *l = ident_list->first;
00757 for (int n = 0; l; n++)
00758 {
00759 if (n) s += ",";
00760 s += l->left->toString() + ":" + l->ql->toString();
00761 l = l->next;
00762 }
00763 }
00764
00765 return s + ")" + oqml_isstat();
00766 }
00767
00768 oqmlNew::newCompile::newCompile(Class *_class, int n)
00769 {
00770 cls = _class;
00771 cnt = n;
00772 attr = idbNewVect(Attribute *, n);
00773 attrname = idbNewVect(char *, n);
00774 list = idbNewVect(oqml_ArrayList *, n);
00775 dot_ctx = idbNewVect(oqmlDotContext *, n);
00776 }
00777
00778 oqmlNew::newCompile::~newCompile()
00779 {
00780 idbFreeIndVect(dot_ctx, cnt);
00781 for (int i = 0; i < cnt; i++)
00782 free(attrname[i]);
00783 free(attrname);
00784
00785 free(attr);
00786 free(list);
00787 }
00788
00789
00790
00791
00792
00793
00794
00795 oqmlDelete::oqmlDelete(oqmlNode * _ql) : oqmlNode(oqmlDELETE)
00796 {
00797 ql = _ql;
00798 }
00799
00800 oqmlDelete::~oqmlDelete()
00801 {
00802 }
00803
00804 oqmlStatus *oqmlDelete::compile(Database *db, oqmlContext *ctx)
00805 {
00806 oqmlStatus *s;
00807 s = ql->compile(db, ctx);
00808
00809 if (s)
00810 return s;
00811
00812 ql->evalType(db, ctx, &eval_type);
00813
00814 if (eval_type.type != oqmlATOM_IDENT && eval_type.type != oqmlATOM_OID &&
00815 eval_type.type != oqmlATOM_UNKNOWN_TYPE)
00816 return oqmlStatus::expected(this, "oid", eval_type.getString());
00817
00818 return oqmlSuccess;
00819 }
00820
00821 oqmlStatus *oqmlDelete::eval(Database *db, oqmlContext *ctx, oqmlAtomList **alist, oqmlComp *, oqmlAtom *)
00822 {
00823 oqmlStatus *s;
00824 oqmlAtomList *al;
00825
00826 s = ql->eval(db, ctx, &al);
00827
00828 if (s) return s;
00829
00830 if (al->cnt == 0)
00831 return oqmlStatus::expected(this, "oid", "nil");
00832
00833 if (al->cnt > 1)
00834 return new oqmlStatus(this, "internal error #112");
00835
00836 oqmlAtom *a = al->first;
00837
00838 if (!OQML_IS_OID(a))
00839 return oqmlStatus::expected(this, "oid", a->type.getString());
00840
00841 Status is = db->removeObject(&OQML_ATOM_OIDVAL(a));
00842
00843 if (is)
00844 return new oqmlStatus(this, is);
00845
00846 *alist = new oqmlAtomList(a);
00847
00848 return oqmlSuccess;
00849 }
00850
00851 void oqmlDelete::evalType(Database *db, oqmlContext *ctx, oqmlAtomType *at)
00852 {
00853 *at = eval_type;
00854 }
00855
00856 oqmlBool oqmlDelete::isConstant() const
00857 {
00858 return oqml_False;
00859 }
00860
00861 std::string
00862 oqmlDelete::toString(void) const
00863 {
00864 if (is_statement)
00865 return std::string("delete ") + ql->toString() + "; ";
00866 return std::string("(delete ") + ql->toString() + ")";
00867 }
00868 }