📄 subsql.cpp
字号:
return -1;
}
offs += strlen(node->sval) + 1;
} 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;
}
} 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -