📄 subsql.cpp
字号:
int dbSubSql::calculateRecordSize(dbList* node, int offs, dbFieldDescriptor* first){ dbFieldDescriptor* fd = first; do { if (node == NULL) { return -1; } if (fd->type == dbField::tpArray) { if (node->type != dbList::nTuple) { return -1; } int nElems = node->aggregate.nComponents; offs = DOALIGN(offs, fd->components->alignment) + nElems*fd->components->dbsSize; if (fd->attr & dbFieldDescriptor::HasArrayComponents) { dbList* component = node->aggregate.components; while (--nElems >= 0) { int d = calculateRecordSize(component,offs,fd->components); if (d < 0) return d; offs = d; component = component->next; } } } else if (fd->type == dbField::tpString) { if (node->type != dbList::nString) { return -1; } offs += strlen(node->sval) + 1; } else if (fd->type == dbField::tpRectangle) { if (node->type != dbList::nTuple) { return -1; } int nCoords = node->aggregate.nComponents; if (nCoords != rectangle::dim*2) { return -1; } dbList* component = node->aggregate.components; while (--nCoords >= 0) { if (component->type != dbList::nInteger && component->type != dbList::nReal) { return -1; } component = component->next; } } else if (fd->type == dbField::tpRawBinary) { if (node->type != dbList::nTuple) { return -1; } int nElems = node->aggregate.nComponents; dbList* component = node->aggregate.components; if (size_t(nElems) > fd->dbsSize) { return -1; } while (--nElems >= 0) { if (component->type != dbList::nInteger || (component->ival & ~0xFF) != 0) { return -1; } component = component->next; }#ifdef AUTOINCREMENT_SUPPORT } else if (node->type == dbList::nAutoinc) { if (fd->type != dbField::tpInt4) { return -1; }#endif } 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; coord_t* coord; 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::tpRectangle: len = node->aggregate.nComponents; component = node->aggregate.components; coord = (coord_t*)(dst + fd->dbsOffs); assert(len == rectangle::dim*2); while (--len >= 0) { *coord++ = (component->type == dbList::nInteger) ? (coord_t)component->ival : (coord_t)component->fval; 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); dbTable* table = (dbTable*)getRow(desc->tableId);#ifdef AUTOINCREMENT_SUPPORT desc->autoincrementCount = table->count;#endif int nRows = table->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) { if (fd->type == dbField::tpRectangle) { dbRtree::insert(this, fd->tTree, oid, fd->dbsOffs); } else { 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -