📄 results.c
字号:
inolog("ReplaceCachedRows %p num_fields=%d num_rows=%d\n", otuple, num_fields, num_rows); for (i = 0; i < num_fields * num_rows; i++, ituple++, otuple++) { if (otuple->value) { free(otuple->value); otuple->value = NULL; } if (ituple->value){ otuple->value = strdup(ituple->value);inolog("[%d,%d] %s copied\n", i / num_fields, i % num_fields, otuple->value);} otuple->len = ituple->len; } return i;}staticint MoveCachedRows(TupleField *otuple, TupleField *ituple, Int2 num_fields, SQLLEN num_rows){ int i;inolog("MoveCachedRows %p num_fields=%d num_rows=%d\n", otuple, num_fields, num_rows); for (i = 0; i < num_fields * num_rows; i++, ituple++, otuple++) { if (otuple->value) { free(otuple->value); otuple->value = NULL; } if (ituple->value) { otuple->value = ituple->value; ituple->value = NULL;inolog("[%d,%d] %s copied\n", i / num_fields, i % num_fields, otuple->value); } otuple->len = ituple->len; ituple->len = -1; } return i;}static BOOL tupleExists(const StatementClass *stmt, const KeySet *keyset){ char selstr[256]; const TABLE_INFO *ti = stmt->ti[0]; QResultClass *res; RETCODE ret = FALSE; if (NAME_IS_VALID(ti->schema_name)) snprintf(selstr, sizeof(selstr), "select 1 from \"%s\".\"%s\" where ctid = '(%d,%d)'", SAFE_NAME(ti->schema_name), SAFE_NAME(ti->table_name), keyset->blocknum, keyset->offset); else snprintf(selstr, sizeof(selstr), "select 1 from \"%s\" where ctid = '(%d,%d)'", SAFE_NAME(ti->table_name), keyset->blocknum, keyset->offset); res = CC_send_query(SC_get_conn(stmt), selstr, NULL, 0, NULL); if (QR_command_maybe_successful(res) && 1 == res->num_cached_rows) ret = TRUE; QR_Destructor(res); return ret;}static BOOL tupleIsAdding(const StatementClass *stmt, const QResultClass *res, SQLLEN index){ SQLLEN i; BOOL ret = FALSE; UWORD status; if (!res->added_keyset) return ret; if (index < res->num_total_read || index >= QR_get_num_total_read(res)) return ret; i = index - res->num_total_read; status = res->added_keyset[i].status; if (0 == (status & CURS_SELF_ADDING)) return ret; if (tupleExists(stmt, res->added_keyset + i)) ret = TRUE; return ret;}static BOOL tupleIsUpdating(const StatementClass *stmt, const QResultClass *res, SQLLEN index){ int i; BOOL ret = FALSE; UWORD status; if (!res->updated || !res->updated_keyset) return ret; for (i = res->up_count - 1; i >= 0; i--) { if (index == res->updated[i]) { status = res->updated_keyset[i].status; if (0 == (status & CURS_SELF_UPDATING)) continue; if (tupleExists(stmt, res->updated_keyset + i)) { ret = TRUE; break; } } } return ret;}static BOOL tupleIsDeleting(const StatementClass *stmt, const QResultClass *res, SQLLEN index){ int i; BOOL ret = FALSE; UWORD status; if (!res->deleted || !res->deleted_keyset) return ret; for (i = 0; i < res->dl_count; i++) { if (index == res->deleted[i]) { status = res->deleted_keyset[i].status; if (0 == (status & CURS_SELF_DELETING)) ; else if (tupleExists(stmt, res->deleted_keyset + i)) ; else ret = TRUE; break; } } return ret;}static BOOL enlargeAdded(QResultClass *res, UInt4 number, const StatementClass *stmt){ UInt4 alloc; int num_fields = res->num_fields; alloc = res->ad_alloc; if (0 == alloc) alloc = number > 10 ? number : 10; else while (alloc < number) { alloc *= 2; } if (alloc <= res->ad_alloc) return TRUE; QR_REALLOC_return_with_error(res->added_keyset, KeySet, sizeof(KeySet) * alloc, res, "enlargeAdded failed", FALSE); if (SQL_CURSOR_KEYSET_DRIVEN != stmt->options.cursor_type) QR_REALLOC_return_with_error(res->added_tuples, TupleField, sizeof(TupleField) * num_fields * alloc, res, "enlargeAdded failed 2", FALSE); res->ad_alloc = alloc; return TRUE;}static void AddAdded(StatementClass *stmt, QResultClass *res, SQLLEN index, const TupleField *tuple_added){ KeySet *added_keyset, *keyset, keys; TupleField *added_tuples = NULL, *tuple; UInt4 ad_count; Int2 num_fields; if (!res) return; num_fields = res->num_fields;inolog("AddAdded index=%d, tuple=%p, num_fields=%d\n", index, tuple_added, num_fields); ad_count = res->ad_count; res->ad_count++; if (QR_get_cursor(res)) index = -(SQLLEN)res->ad_count; if (!tuple_added) return; KeySetSet(tuple_added, num_fields + res->num_key_fields, res->num_key_fields, &keys); keys.status = SQL_ROW_ADDED; if (CC_is_in_trans(SC_get_conn(stmt))) keys.status |= CURS_SELF_ADDING; else keys.status |= CURS_SELF_ADDED; AddRollback(stmt, res, index, &keys, SQL_ADD); if (!QR_get_cursor(res)) return; if (ad_count > 0 && 0 == res->ad_alloc) return; if (!enlargeAdded(res, ad_count + 1, stmt)) return; added_keyset = res->added_keyset; added_tuples = res->added_tuples; keyset = added_keyset + ad_count; *keyset = keys; if (added_tuples) { tuple = added_tuples + num_fields * ad_count; memset(tuple, 0, sizeof(TupleField) * num_fields); ReplaceCachedRows(tuple, tuple_added, num_fields, 1); }}static void RemoveAdded(QResultClass *, SQLLEN);static void RemoveUpdated(QResultClass *, SQLLEN);static void RemoveUpdatedAfterTheKey(QResultClass *, SQLLEN, const KeySet*);static void RemoveDeleted(QResultClass *, SQLLEN);static void RemoveAdded(QResultClass *res, SQLLEN index){ SQLLEN rmidx, mv_count; Int2 num_fields = res->num_fields; KeySet *added_keyset; TupleField *added_tuples; mylog("RemoveAdded index=%d\n", index); if (index < 0) rmidx = -index - 1; else rmidx = index - res->num_total_read; if (rmidx >= res->ad_count) return; added_keyset = res->added_keyset + rmidx; added_tuples = res->added_tuples + num_fields * rmidx; ClearCachedRows(added_tuples, num_fields, 1); mv_count = res->ad_count - rmidx - 1; if (mv_count > 0) { memmove(added_keyset, added_keyset + 1, mv_count * sizeof(KeySet)); memmove(added_tuples, added_tuples + num_fields, mv_count * num_fields * sizeof(TupleField)); } RemoveDeleted(res, index); RemoveUpdated(res, index); res->ad_count--; mylog("RemoveAdded removed=1 count=%d\n", res->ad_count);}static void CommitAdded(QResultClass *res){ KeySet *added_keyset; int i; UWORD status; mylog("CommitAdded res=%p\n", res); if (!res || !res->added_keyset) return; added_keyset = res->added_keyset; for (i = res->ad_count - 1; i >= 0; i--) { status = added_keyset[i].status; if (0 != (status & CURS_SELF_ADDING)) { status |= CURS_SELF_ADDED; status &= ~CURS_SELF_ADDING; } if (0 != (status & CURS_SELF_UPDATING)) { status |= CURS_SELF_UPDATED; status &= ~CURS_SELF_UPDATING; } if (0 != (status & CURS_SELF_DELETING)) { status |= CURS_SELF_DELETED; status &= ~CURS_SELF_DELETING; } if (status != added_keyset[i].status) {inolog("!!Commit Added=%d(%d)\n", QR_get_num_total_read(res) + i, i); added_keyset[i].status = status; } }}int AddDeleted(QResultClass *res, SQLULEN index, KeySet *keyset){ int i; Int2 dl_count, new_alloc; SQLULEN *deleted; KeySet *deleted_keyset; UWORD status; Int2 num_fields = res->num_fields;inolog("AddDeleted %d\n", index); if (!res) return FALSE; dl_count = res->dl_count; res->dl_count++; if (!QR_get_cursor(res)) return TRUE; if (!res->deleted) { dl_count = 0; new_alloc = 10; QR_MALLOC_return_with_error(res->deleted, SQLULEN, sizeof(SQLULEN) * new_alloc, res, "Deleted index malloc error", FALSE); QR_MALLOC_return_with_error(res->deleted_keyset, KeySet, sizeof(KeySet) * new_alloc, res, "Deleted keyset malloc error", FALSE); deleted = res->deleted; deleted_keyset = res->deleted_keyset; res->dl_alloc = new_alloc; } else { if (dl_count >= res->dl_alloc) { new_alloc = res->dl_alloc * 2; res->dl_alloc = 0; QR_REALLOC_return_with_error(res->deleted, SQLULEN, sizeof(SQLULEN) * new_alloc, res, "Dleted index realloc error", FALSE); deleted = res->deleted; QR_REALLOC_return_with_error(res->deleted_keyset, KeySet, sizeof(KeySet) * new_alloc, res, "Dleted KeySet realloc error", FALSE); deleted_keyset = res->deleted_keyset; res->dl_alloc = new_alloc; } /* sort deleted indexes in ascending order */ for (i = 0, deleted = res->deleted, deleted_keyset = res->deleted_keyset; i < dl_count; i++, deleted++, deleted_keyset += num_fields) { if (index < *deleted) break; } memmove(deleted + 1, deleted, sizeof(SQLLEN) * (dl_count - i)); memmove(deleted_keyset + 1, deleted_keyset, sizeof(KeySet) * (dl_count - i)); } *deleted = index; *deleted_keyset = *keyset; status = keyset->status; status &= (~KEYSET_INFO_PUBLIC); status |= SQL_ROW_DELETED; if (CC_is_in_trans(QR_get_conn(res))) { status |= CURS_SELF_DELETING; QR_get_conn(res)->result_uncommitted = 1; } else { status &= ~(CURS_SELF_ADDING | CURS_SELF_UPDATING | CURS_SELF_DELETING); status |= CURS_SELF_DELETED; } deleted_keyset->status = status; res->dl_count = dl_count + 1; return TRUE;}static void RemoveDeleted(QResultClass *res, SQLLEN index){ int i, mv_count, rm_count = 0; SQLLEN pidx, midx; SQLULEN *deleted, num_read = QR_get_num_total_read(res); KeySet *deleted_keyset; mylog("RemoveDeleted index=%d\n", index); if (index < 0) { midx = index; pidx = num_read - index - 1; } else { pidx = index; if (index >= num_read) midx = num_read - index - 1; else midx = index; } for (i = 0; i < res->dl_count; i++) { if (pidx == res->deleted[i] || midx == res->deleted[i]) { mv_count = res->dl_count - i - 1; if (mv_count > 0) { deleted = res->deleted + i; deleted_keyset = res->deleted_keyset + i; memmove(deleted, deleted + 1, mv_count * sizeof(SQLULEN)); memmove(deleted_keyset, deleted_keyset + 1, mv_count * sizeof(KeySet)); } res->dl_count--; rm_count++; } } mylog("RemoveDeleted removed count=%d,%d\n", rm_count, res->dl_count);}static void CommitDeleted(QResultClass *res){ int i; SQLULEN *deleted; KeySet *deleted_keyset; UWORD status; if (!res->deleted) return; for (i = 0, deleted = res->deleted, deleted_keyset = res->deleted_keyset; i < res->dl_count; i++, deleted++, deleted_keyset++) { status = deleted_keyset->status; if (0 != (status & CURS_SELF_ADDING)) { status |= CURS_SELF_ADDED; status &= ~CURS_SELF_ADDING; } if (0 != (status & CURS_SELF_UPDATING)) { status |= CURS_SELF_UPDATED; status &= ~CURS_SELF_UPDATING; } if (0 != (status & CURS_SELF_DELETING)) { status |= CURS_SELF_DELETED; status &= ~CURS_SELF_DELETING; } if (status != deleted_keyset->status) {inolog("!!Commit Deleted=%d(%d)\n", *deleted, i); deleted_keyset->status = status; } } }static BOOL enlargeUpdated(QResultClass *res, Int4 number, const StatementClass *stmt){ Int2 alloc; alloc = res->up_alloc; if (0 == alloc) alloc = number > 10 ? number : 10; else while (alloc < number) { alloc *= 2; } if (alloc <= res->up_alloc) return TRUE; QR_REALLOC_return_with_error(res->updated, UInt4, sizeof(UInt4) * alloc, res, "enlargeUpdated failed", FALSE); QR_REALLOC_return_with_error(res->updated_keyset, KeySet, sizeof(KeySet) * alloc, res, "enlargeUpdated failed 2", FALSE); if (SQL_CURSOR_KEYSET_DRIVEN != stmt->options.cursor_type) QR_REALLOC_return_with_error(res->updated_tuples, TupleField, sizeof(TupleField) * res->num_fields * alloc, res, "enlargeUpdated 3", FALSE); res->up_alloc = alloc; return TRUE;}static void AddUpdated(StatementClass *stmt, SQLLEN index){ QResultClass *res; SQLULEN *updated; KeySet *updated_keyset, *keyset; TupleField *updated_tuples = NULL, *tuple_updated, *tuple; SQLULEN kres_ridx; UInt2 up_count; BOOL is_in_trans; SQLLEN upd_idx, upd_add_idx; Int2 num_fields; int i; UWORD status;inolog("AddUpdated index=%d\n", index); if (!stmt) return; if (res = SC_get_Curres(stmt), !res) return; if (!res->keyset) return; kres_ridx = GIdx2KResIdx(index, stmt, res); if (kres_ridx < 0 || kres_ridx >= res->num_cached_keys) return; keyset = res->keyset + kres_ridx; if (0 != (keyset->status & CURS_SELF_ADDING)) AddRollback(stmt, res, index, res->keyset + kres_ridx, SQL_REFRESH); if (!QR_get_cursor(res)) return; up_count = res->up_count; if (up_count > 0 && 0 == res->up_alloc) return; num_fields = res->num_fields; tuple_updated = res->backend_tuples + kres_ridx * num_fields; if (!tuple_updated) return; upd_idx = -1; upd_add_idx = -1; updated = res->updated; is_in_trans = CC_is_in_trans(SC_get_conn(stmt)); updated_keyset = res->updated_keyset; status = keyset->status; status &= (~KEYSET_INFO_PUBLIC); status |= SQL_ROW_UPDATED; if (is_in_trans) status |= CURS_SELF_UPDATING; else { for (i = up_count - 1; i >= 0; i--) { if (updated[i] == index) break; } if (i >= 0) upd_idx = i; else { SQLLEN num_totals = QR_get_num_total_tuples(res); if (index >= num_totals) upd_add_idx = num_totals - index; } status |= CURS_SELF_UPDATED; status &= ~(CURS_SELF_ADDING | CURS_SELF_UPDATING | CURS_SELF_DELETING); } tuple = NULL; /* update the corresponding add(updat)ed info */ if (upd_add_idx >= 0) { res->added_keyset[upd_add_idx].status = status; if (res->added_tuples) { tuple
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -