📄 subsql.cpp
字号:
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;
continue;
case tpString:
*(int4*)dst = (int1)atoi((char*)sattr.base);
continue;
}
break;
case dbField::tpInt8:
switch (expr->type) {
case tpInteger:
*(db_int8*)dst = sattr.ivalue;
continue;
case tpBoolean:
*(db_int8*)dst = sattr.bvalue ? 1 : 0;
continue;
case tpReal:
*(db_int8*)dst = (db_int8)sattr.fvalue;
continue;
case tpString:
*(db_int8*)dst = (db_int8)atoi((char*)sattr.base);
continue;
}
break;
case dbField::tpReal4:
switch (expr->type) {
case tpInteger:
*(real4*)dst = (real4)sattr.ivalue;
continue;
case tpBoolean:
*(real4*)dst = (real4)(sattr.bvalue ? 1 : 0);
continue;
case tpReal:
*(real4*)dst = (real4)sattr.fvalue;
continue;
case tpString:
*(real4*)dst = (real4)atof((char*)sattr.base);
continue;
}
break;
case dbField::tpReal8:
switch (expr->type) {
case tpInteger:
*(real8*)dst = (real8)sattr.ivalue;
continue;
case tpBoolean:
*(real8*)dst = sattr.bvalue ? 1.0 : 0.0;
continue;
case tpReal:
*(real8*)dst = sattr.fvalue;
continue;
case tpString:
*(real8*)dst = atof((char*)sattr.base);
continue;
}
break;
case dbField::tpString:
src = buf;
switch (expr->type) {
case tpInteger:
sprintf(buf, INT8_FORMAT, sattr.ivalue);
break;
case tpBoolean:
strcpy(buf, sattr.bvalue ? "t" : "f");
break;
case tpReal:
sprintf(buf, "%f", sattr.fvalue);
break;
case tpString:
src = (char*)sattr.base;
break;
}
*(char**)dst = new char[strlen(src)+1];
strcpy(*(char**)dst, src);
elems->strValue = *(char**)dst;
continue;
case dbField::tpReference:
if (expr->type == tpInteger) {
*(oid_t*)dst = sattr.oid;
continue;
}
}
assert(false);
} while ((elems = elems->next) != NULL);
return true;
}
void dbSubSql::deleteColumns(dbFieldDescriptor* columns)
{
if (columns != NULL) {
dbFieldDescriptor *next, *fd = columns;
do {
next = fd->next;
fd->type = dbField::tpUnknown;
fd->longName = NULL;
delete fd;
fd = next;
} while (next != columns);
}
}
void dbSubSql::profile()
{
printf("TABLES:\n");
printf(" Fixed Fields Columns Rows Total Aligned TableName\n");
printf("----------------------------------------------------------------\n");
beginTransaction(dbSharedLock);
for (dbTableDescriptor* desc=tables; desc != NULL; desc=desc->nextDbTable)
{
dbRecord* rec;
dbTable* table = (dbTable*)getRow(desc->tableId);
size_t totalSize = 0;
size_t totalAlignedSize = 0;
for (oid_t oid = table->firstRow; oid != 0; oid = rec->next) {
rec = getRow(oid);
totalSize += rec->size;
totalAlignedSize += DOALIGN(rec->size, dbAllocationQuantum);
}
printf("%8ld %8ld %8ld %8ld %8ld %8ld %s\n",
(long)desc->fixedSize,(long)desc->nFields, (long)desc->nColumns,
(long)table->nRows, (long)totalSize, (long)totalAlignedSize,
desc->name);
}
}
bool dbSubSql::parse()
{
dbTableDescriptor* desc;
dbFieldDescriptor* fd;
int tkn;
bool count, outputOid, compactify;
dbFieldDescriptor* columns;
line = 1;
pos = 0;
while (true) {
if (in == stdin) {
printf(prompt);
tkn = scan();
pos += strlen(prompt);
} else {
tkn = scan();
}
switch (tkn) {
case tkn_update:
if (!opened) {
error("Database not opened");
continue;
}
if (accessType == dbReadOnly) {
error("Operation is not possible in read-only mode");
continue;
}
dotIsPartOfIdentifier = true;
if (expect("table name", tkn_ident)) {
if ((desc = findTable(name)) == NULL) {
error("No such table in database");
continue;
}
if (!expect("set", tkn_set)) {
continue;
}
dbDatabaseThreadContext* ctx = threadContext.get();
byte *record = dbMalloc(desc->appSize);
memset(record, 0, desc->appSize);
ctx->interactive = true;
ctx->catched = true;
dbUpdateElement* elems = NULL;
if (!expect("field name", tkn_ident)) {
goto updateCleanup;
}
#ifdef THROW_EXCEPTION_ON_ERROR
try {
#else
if (setjmp(ctx->unwind) == 0) {
#endif
char* condition = NULL;
int startPos = pos;
while (true) {
dbUpdateElement* elem = new dbUpdateElement;
dbFieldDescriptor* fd = desc->findSymbol(name);
if (fd == NULL) {
error("No such field in the table");
goto updateCleanup;
}
if (fd->type > dbField::tpReference) {
error("Field can not be updated");
goto updateCleanup;
}
elem->field = fd;
elem->next = elems;
elems = elem;
if (!expect("=", tkn_eq)) {
goto updateCleanup;
}
startPos = pos;
int ch = readExpression();
if (ch == EOF) {
error("unexpected end of input");
goto updateCleanup;
}
condition = strstr(buf, "where");
if (condition != NULL) {
*condition = '\0';
}
dbExprNode* expr = ctx->compiler.compileExpression(desc, buf, startPos);
if (expr == NULL) {
goto updateCleanup;
}
if (expr->type > tpString) {
error("Invalid expression type");
goto updateCleanup;
}
elem->value = expr;
if (condition == NULL && ch == ',') {
if (!expect("field name", tkn_ident)) {
goto updateCleanup;
}
} else {
break;
}
}
dbAnyCursor cursor(*desc, dbCursorForUpdate, record);
cursor.reset();
if (condition != NULL) {
query.pos = startPos + (condition - buf) + 5;
query = (char const*)(condition + 5);
select(&cursor, query);
if (query.compileError()) {
goto updateCleanup;
}
} else {
select(&cursor);
}
if (cursor.gotoFirst()) {
do {
cursor.fetch();
if (!updateFields(&cursor, elems)) {
goto updateCleanup;
}
cursor.update();
} while (cursor.gotoNext());
}
printf("\n\t%d records updated\n", cursor.getNumberOfRecords());
#ifdef THROW_EXCEPTION_ON_ERROR
} catch(dbException const&) {}
#else
} else {
if (query.mutexLocked) {
query.mutexLocked = false;
query.mutex.unlock();
}
}
#endif
updateCleanup:
query.reset();
while (elems != NULL) {
dbUpdateElement* elem = elems;
elems = elems->next;
delete elem;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -