📄 subsql.cpp
字号:
return -1; } component = component->next; } } else { if (!((node->type == dbList::nBool && fd->type == dbField::tpBool) || (node->type == dbList::nInteger && (fd->type == dbField::tpInt1 || fd->type == dbField::tpInt2 || fd->type == dbField::tpInt4 || fd->type == dbField::tpInt8 || fd->type == dbField::tpReference)) || (node->type == dbList::nReal && (fd->type == dbField::tpReal4 || fd->type == dbField::tpReal8)) || (node->type == dbList::nTuple && fd->type == dbField::tpStructure))) { return -1; } if (fd->attr & dbFieldDescriptor::HasArrayComponents) { int d = calculateRecordSize(node->aggregate.components, offs, fd->components); if (d < 0) return d; offs = d; } } node = node->next; } while ((fd = fd->next) != first); return offs; }bool dbSubSql::isValidOid(oid_t oid) { return oid == 0 || (oid < currIndexSize && (currIndex[oid] & (dbFreeHandleMarker|dbInternalObjectMarker)) == 0);}int dbSubSql::initializeRecordFields(dbList* node, byte* dst, int offs, dbFieldDescriptor* first){ dbFieldDescriptor* fd = first; dbList* component; byte* elem; int len, elemOffs, elemSize; do { if (node->type == dbList::nString && fd->type != dbField::tpString) { char* s = node->sval; long ival; switch (fd->type) { case dbField::tpBool: *(bool*)(dst+fd->dbsOffs) = *s == '1' || *s == 't' || *s == 'T'; break; case dbField::tpInt1: if (sscanf(s, "%ld", &ival) != 1) { return -1; } *(int1*)(dst+fd->dbsOffs) = (int1)ival; case dbField::tpInt2: if (sscanf(s, "%ld", &ival) != 1) { return -1; } *(int2*)(dst+fd->dbsOffs) = (int2)ival; case dbField::tpInt4: if (sscanf(s, "%ld", &ival) != 1) { return -1; } *(int4*)(dst+fd->dbsOffs) = (int4)ival; case dbField::tpInt8: if (sscanf(s, "%ld", &ival) != 1) { return -1; } *(db_int8*)(dst+fd->dbsOffs) = ival; break; case dbField::tpReal4: if (sscanf(s, "%f", (real4*)(dst+fd->dbsOffs)) != 1) { return -1; } break; case dbField::tpReal8: if (sscanf(s, "%lf", (real8*)(dst+fd->dbsOffs)) != 1) { return -1; } break; }#ifdef AUTOINCREMENT_SUPPORT } else if (node->type == dbList::nAutoinc) { if (fd->type != dbField::tpInt4) { *(int4*)(dst+fd->dbsOffs) = fd->defTable->autoincrementCount; } else { return -1; }#endif } else { switch (fd->type) { case dbField::tpBool: *(bool*)(dst+fd->dbsOffs) = node->bval; break; case dbField::tpInt1: *(int1*)(dst+fd->dbsOffs) = (int1)node->ival; break; case dbField::tpInt2: *(int2*)(dst+fd->dbsOffs) = (int2)node->ival; break; case dbField::tpInt4: *(int4*)(dst+fd->dbsOffs) = (int4)node->ival; break; case dbField::tpInt8: *(db_int8*)(dst+fd->dbsOffs) = node->ival; break; case dbField::tpReal4: *(real4*)(dst+fd->dbsOffs) = (real4)node->fval; break; case dbField::tpReal8: *(real8*)(dst+fd->dbsOffs) = node->fval; break; case dbField::tpReference: if (isValidOid((oid_t)node->ival)) { *(oid_t*)(dst+fd->dbsOffs) = (oid_t)node->ival; } else { return -1; } break; case dbField::tpString: ((dbVarying*)(dst+fd->dbsOffs))->offs = offs; len = strlen(node->sval) + 1; ((dbVarying*)(dst+fd->dbsOffs))->size = len; memcpy(dst + offs, node->sval, len); offs += len; break; case dbField::tpRawBinary: len = node->aggregate.nComponents; component = node->aggregate.components; elem = dst + fd->dbsOffs; while (--len >= 0) { *elem++ = (byte)component->ival; component = component->next; } break; case dbField::tpArray: len = node->aggregate.nComponents; elem = (byte*)DOALIGN(long(dst) + offs, fd->components->alignment); offs = elem - dst; ((dbVarying*)(dst+fd->dbsOffs))->offs = offs; ((dbVarying*)(dst+fd->dbsOffs))->size = len; elemSize = fd->components->dbsSize; elemOffs = len*elemSize; offs += elemOffs; component = node->aggregate.components; while (--len >= 0) { elemOffs = initializeRecordFields(component, elem, elemOffs, fd->components); elemOffs -= elemSize; elem += elemSize; component = component->next; } offs += elemOffs; break; case dbField::tpStructure: offs = initializeRecordFields(node->aggregate.components, dst, offs, fd->components); } } node = node->next; } while ((fd = fd->next) != first); return offs;}bool dbSubSql::insertRecord(dbList* list, dbTableDescriptor* desc){ int size = calculateRecordSize(list, desc->fixedSize, desc->columns); if (size < 0) { error("Incompatible types in insert statement"); return false; } oid_t oid = allocateRow(desc->tableId, size); byte* dst = (byte*)getRow(oid); initializeRecordFields(list, dst, desc->fixedSize, desc->columns); int nRows = ((dbTable*)getRow(desc->tableId))->nRows; dbFieldDescriptor* fd; for (fd = desc->hashedFields; fd != NULL; fd = fd->nextHashedField){ dbHashTable::insert(this, fd->hashTable, oid, fd->type, fd->dbsSize, fd->dbsOffs, nRows); } for (fd = desc->indexedFields; fd != NULL; fd = fd->nextIndexedField) { dbTtree::insert(this, fd->tTree, oid, fd->type, fd->dbsSize, fd->comparator, fd->dbsOffs); } return true;}int dbSubSql::readValues(dbList** chain){ int i, n = 0; int tkn; dbList* node; while (true) { switch (scan()) { case tkn_lpar: node = new dbList(dbList::nTuple); node->aggregate.components = NULL; i = readValues(&node->aggregate.components); if (i < 0) { return -1; } node->aggregate.nComponents = i; break; case tkn_rpar: return -n; // valid only in case of empty list case tkn_iconst: node = new dbList(dbList::nInteger); node->ival = ival; break; case tkn_true: node = new dbList(dbList::nBool); node->bval = true; break; case tkn_false: node = new dbList(dbList::nBool); node->bval = false; break; case tkn_fconst: node = new dbList(dbList::nReal); node->fval = fval; break; case tkn_sconst: node = new dbList(dbList::nString); node->sval = new char[strlen(buf)+1]; strcpy(node->sval, buf); break; case tkn_autoincrement: node = new dbList(dbList::nAutoinc); break; case tkn_error: return -1; default: error("Syntax error in insert list"); return -1; } *chain = node; chain = &node->next; n += 1; if ((tkn = scan()) == tkn_rpar) { return n; } if (tkn != tkn_comma) { error("',' expected"); return -1; } }}dbFieldDescriptor* dbSubSql::readFieldName(){ int tkn; if (expect("table name", tkn_ident)) { dbTableDescriptor* desc; dbFieldDescriptor* fd; if ((desc = findTable(name)) == NULL) { error("No such table in database"); return NULL; } if (expect(".", tkn_dot) && expect("field name", tkn_ident)) { if ((fd = desc->findSymbol(name)) == NULL) { error("No such field in the table"); return NULL; } else if (fd->type == dbField::tpArray) { error("Array components can not be indexed"); return NULL; } } else { return NULL; } while ((tkn = scan()) != tkn_semi) { if (tkn != tkn_dot) { error("'.' expected"); return NULL; } if (expect("field name", tkn_ident)) { if ((fd = fd->find(name)) == NULL) { error("No such field in the table"); return NULL; } else if (fd->type == dbField::tpArray) { error("Array components can not be indexed"); return NULL; } } else { return NULL; } } if (fd->type == dbField::tpStructure) { error("Structures can not be indexed"); return NULL; } return fd; } return NULL;}bool dbSubSql::updateFields(dbAnyCursor* cursor, dbUpdateElement* elems){ char buf[64], *src; dbInheritedAttribute iattr; dbSynthesizedAttribute sattr; iattr.db = this; iattr.oid = cursor->currId; iattr.table = (dbTable*)getRow(cursor->table->tableId); iattr.record = (byte*)getRow(cursor->currId); iattr.paramBase = (size_t)cursor->paramBase; do { dbExprNode* expr = elems->value; dbFieldDescriptor* fd = elems->field; execute(expr, iattr, sattr); byte* dst = cursor->record + fd->appOffs; switch (fd->type) { case dbField::tpBool: switch (expr->type) { case tpInteger: *(bool*)dst = sattr.ivalue != 0; continue; case tpBoolean: *(bool*)dst = sattr.bvalue; continue; case tpReal: *(bool*)dst = sattr.fvalue != 0; continue; case tpString: *(bool*)dst = *sattr.base == 'T' || *sattr.base == 't' || *sattr.base == '1'; continue; } break; case dbField::tpInt1: switch (expr->type) { case tpInteger: *(int1*)dst = (int1)sattr.ivalue; continue; case tpBoolean: *(int1*)dst = sattr.bvalue ? 1 : 0; continue; case tpReal: *(int1*)dst = (int1)sattr.fvalue; continue; case tpString: *(int1*)dst = (int1)atoi((char*)sattr.base); continue; } break; case dbField::tpInt2: switch (expr->type) { case tpInteger: *(int2*)dst = (int2)sattr.ivalue; continue; case tpBoolean: *(int2*)dst = sattr.bvalue ? 1 : 0; continue; case tpReal: *(int2*)dst = (int2)sattr.fvalue; continue; case tpString: *(int2*)dst = (int2)atoi((char*)sattr.base); continue; } break; case dbField::tpInt4: switch (expr->type) { case tpInteger: *(int4*)dst = (int4)sattr.ivalue; continue; case tpBoolean: *(int4*)dst = sattr.bvalue ? 1 : 0; continue; case tpReal: *(int4*)dst = (int4)sattr.fvalue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -