mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-04-30 09:41:39 +08:00
Enable multi-page temp tables
This commit is contained in:
parent
8fa51d0431
commit
56995ff968
10
ChangeLog
10
ChangeLog
@ -1,5 +1,13 @@
|
||||
Wed Sep 8 22:24:29 CDT 2004 Jeff Smith <whydoubt@yahoo.com>
|
||||
* HACKING: Small format documention correction
|
||||
* HACKING: Small format documentation correction
|
||||
* include/mdbtools.h:
|
||||
* src/libmdb/data.c:
|
||||
* src/libmdb/table.c:
|
||||
* src/libmdb/worktable.c:
|
||||
* src/libmdb/write.c:
|
||||
* src/odbc/odbc.c:
|
||||
* src/sql/mdbsql.c:
|
||||
* src/util/mdb-sql.c: Enable multi-page temp tables
|
||||
|
||||
Wed Sep 8 07:37:08 CDT 2004 Jeff Smith <whydoubt@yahoo.com>
|
||||
* include/mdbtools.h:
|
||||
|
@ -346,6 +346,9 @@ typedef struct {
|
||||
MdbIndexChain *chain;
|
||||
MdbProperties *props;
|
||||
unsigned int num_var_cols; /* to know if row has variable columns */
|
||||
/* temp table */
|
||||
unsigned int is_temp_table;
|
||||
GPtrArray *temp_table_pages;
|
||||
} MdbTableDef;
|
||||
|
||||
struct mdbindex {
|
||||
|
@ -342,12 +342,26 @@ mdb_fetch_row(MdbTableDef *table)
|
||||
if (!table->cur_pg_num) {
|
||||
table->cur_pg_num=1;
|
||||
table->cur_row=0;
|
||||
if (table->strategy!=MDB_INDEX_SCAN)
|
||||
if ((!table->is_temp_table)&&(table->strategy!=MDB_INDEX_SCAN))
|
||||
if (!mdb_read_next_dpg(table)) return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
if (table->strategy==MDB_INDEX_SCAN) {
|
||||
if (table->is_temp_table) {
|
||||
GPtrArray *pages = table->temp_table_pages;
|
||||
rows = mdb_get_int16(
|
||||
g_ptr_array_index(pages, table->cur_pg_num-1),
|
||||
fmt->row_count_offset);
|
||||
if (table->cur_row >= rows) {
|
||||
table->cur_row = 0;
|
||||
table->cur_pg_num++;
|
||||
if (table->cur_pg_num > pages->len)
|
||||
return 0;
|
||||
}
|
||||
memcpy(mdb->pg_buf,
|
||||
g_ptr_array_index(pages, table->cur_pg_num-1),
|
||||
fmt->pg_size);
|
||||
} else if (table->strategy==MDB_INDEX_SCAN) {
|
||||
|
||||
if (!mdb_index_find_next(table->mdbidx, table->scan_idx, table->chain, &pg, (guint16 *) &(table->cur_row))) {
|
||||
mdb_index_scan_free(table);
|
||||
|
@ -56,6 +56,12 @@ MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry)
|
||||
void mdb_free_tabledef(MdbTableDef *table)
|
||||
{
|
||||
if (!table) return;
|
||||
if (table->is_temp_table) {
|
||||
unsigned int i;
|
||||
for (i=0; i<table->temp_table_pages->len; i++)
|
||||
g_free(g_ptr_array_index(table->temp_table_pages,i));
|
||||
g_ptr_array_free(table->temp_table_pages, TRUE);
|
||||
}
|
||||
mdb_free_columns(table->columns);
|
||||
mdb_free_indices(table->indices);
|
||||
g_free(table->usage_map);
|
||||
|
@ -62,6 +62,8 @@ mdb_create_temp_table(MdbHandle *mdb, char *name)
|
||||
|
||||
table = mdb_alloc_tabledef(entry);
|
||||
table->columns = g_ptr_array_new();
|
||||
table->is_temp_table = 1;
|
||||
table->temp_table_pages = g_ptr_array_new();
|
||||
|
||||
return table;
|
||||
}
|
||||
|
@ -449,14 +449,14 @@ mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, int unsigned num_fie
|
||||
int
|
||||
mdb_pg_get_freespace(MdbHandle *mdb)
|
||||
{
|
||||
MdbFormatConstants *fmt = mdb->fmt;
|
||||
int rows, free_start, free_end;
|
||||
int rows, free_start, free_end;
|
||||
int row_count_offset = mdb->fmt->row_count_offset;
|
||||
|
||||
rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
|
||||
free_start = fmt->row_count_offset + 2 + (rows * 2);
|
||||
free_end = mdb_pg_get_int16(mdb, (fmt->row_count_offset + rows * 2)) -1;
|
||||
rows = mdb_pg_get_int16(mdb, row_count_offset);
|
||||
free_start = row_count_offset + 2 + (rows * 2);
|
||||
free_end = mdb_pg_get_int16(mdb, row_count_offset + (rows * 2));
|
||||
mdb_debug(MDB_DEBUG_WRITE,"free space left on page = %d", free_end - free_start);
|
||||
return (free_end - free_start + 1);
|
||||
return (free_end - free_start);
|
||||
}
|
||||
unsigned char *
|
||||
mdb_new_leaf_pg(MdbCatalogEntry *entry)
|
||||
@ -475,13 +475,14 @@ mdb_new_leaf_pg(MdbCatalogEntry *entry)
|
||||
unsigned char *
|
||||
mdb_new_data_pg(MdbCatalogEntry *entry)
|
||||
{
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
MdbFormatConstants *fmt = entry->mdb->fmt;
|
||||
unsigned char *new_pg;
|
||||
|
||||
new_pg = (unsigned char *) g_malloc0(mdb->fmt->pg_size);
|
||||
new_pg = (unsigned char *) g_malloc0(fmt->pg_size);
|
||||
|
||||
new_pg[0]=0x01;
|
||||
new_pg[1]=0x01;
|
||||
_mdb_put_int16(new_pg, 2, fmt->pg_size - fmt->row_count_offset - 2);
|
||||
_mdb_put_int32(new_pg, 4, entry->table_pg);
|
||||
|
||||
return new_pg;
|
||||
@ -613,19 +614,37 @@ mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_siz
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
MdbFormatConstants *fmt = mdb->fmt;
|
||||
|
||||
new_pg = mdb_new_data_pg(entry);
|
||||
if (table->is_temp_table) {
|
||||
GPtrArray *pages = table->temp_table_pages;
|
||||
if (pages->len == 0) {
|
||||
new_pg = mdb_new_data_pg(entry);
|
||||
g_ptr_array_add(pages, new_pg);
|
||||
} else {
|
||||
new_pg = g_ptr_array_index(pages, pages->len - 1);
|
||||
if (mdb_get_int16(new_pg, 2) < new_row_size + 2) {
|
||||
new_pg = mdb_new_data_pg(entry);
|
||||
g_ptr_array_add(pages, new_pg);
|
||||
}
|
||||
}
|
||||
|
||||
num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
|
||||
pos = mdb->fmt->pg_size;
|
||||
num_rows = mdb_get_int16(new_pg, fmt->row_count_offset);
|
||||
pos = (num_rows == 0) ? fmt->pg_size :
|
||||
mdb_get_int16(new_pg, fmt->row_count_offset + (num_rows*2));
|
||||
} else { /* is not a temp table */
|
||||
new_pg = mdb_new_data_pg(entry);
|
||||
|
||||
/* copy existing rows */
|
||||
for (i=0;i<num_rows;i++) {
|
||||
row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
|
||||
row_end = mdb_find_end_of_row(mdb, i);
|
||||
row_size = row_end - row_start + 1;
|
||||
pos -= row_size;
|
||||
memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
|
||||
_mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
|
||||
num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
|
||||
pos = fmt->pg_size;
|
||||
|
||||
/* copy existing rows */
|
||||
for (i=0;i<num_rows;i++) {
|
||||
row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
|
||||
row_end = mdb_find_end_of_row(mdb, i);
|
||||
row_size = row_end - row_start + 1;
|
||||
pos -= row_size;
|
||||
memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
|
||||
_mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
|
||||
}
|
||||
}
|
||||
|
||||
/* add our new row */
|
||||
@ -638,12 +657,14 @@ mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_siz
|
||||
num_rows++;
|
||||
_mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
|
||||
|
||||
/* copy new page over old */
|
||||
memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
|
||||
g_free(new_pg);
|
||||
|
||||
/* update the freespace */
|
||||
_mdb_put_int16(mdb->pg_buf, 2, mdb_pg_get_freespace(mdb));
|
||||
_mdb_put_int16(new_pg,2,pos - fmt->row_count_offset - 2 - (num_rows*2));
|
||||
|
||||
/* copy new page over old */
|
||||
if (!table->is_temp_table) {
|
||||
memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
|
||||
g_free(new_pg);
|
||||
}
|
||||
|
||||
return num_rows;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#include "connectparams.h"
|
||||
|
||||
static char software_version[] = "$Id: odbc.c,v 1.18 2004/05/30 08:06:43 whydoubt Exp $";
|
||||
static char software_version[] = "$Id: odbc.c,v 1.19 2004/09/09 03:44:36 whydoubt Exp $";
|
||||
static void *no_unused_var_warn[] = {software_version,
|
||||
no_unused_var_warn};
|
||||
|
||||
@ -851,7 +851,7 @@ struct _henv *env = (struct _henv *) dbc->henv;
|
||||
//cur = cur->next;
|
||||
//}
|
||||
|
||||
if (mdb_sql_fetch_row(env->sql, env->sql->cur_table)) {
|
||||
if (mdb_fetch_row(env->sql->cur_table)) {
|
||||
stmt->rows_affected++;
|
||||
return SQL_SUCCESS;
|
||||
} else {
|
||||
@ -1293,11 +1293,6 @@ SQLRETURN SQL_API SQLGetTypeInfo(
|
||||
mdb_sql_add_temp_col(sql, ttable, 17, "NUM_PREC_RADIX", MDB_INT, 0, 1);
|
||||
mdb_sql_add_temp_col(sql, ttable, 18, "INTERVAL_PRECISION", MDB_INT, 0, 1);
|
||||
|
||||
/* blank out the pg_buf */
|
||||
new_pg = mdb_new_data_pg(ttable->entry);
|
||||
memcpy(mdb->pg_buf, new_pg, mdb->fmt->pg_size);
|
||||
g_free(new_pg);
|
||||
|
||||
for (i=0; i<MAX_TYPE_INFO; i++) {
|
||||
if (!fSqlType || fSqlType == type_info[i].data_type) {
|
||||
tmpsiz = mdb_ascii2unicode(mdb, type_info[i].type_name, 0, 100, tmpstr);
|
||||
@ -1330,7 +1325,6 @@ SQLRETURN SQL_API SQLGetTypeInfo(
|
||||
ttable->num_rows++;
|
||||
}
|
||||
}
|
||||
sql->kludge_ttable_pg = g_memdup(mdb->pg_buf, mdb->fmt->pg_size);
|
||||
sql->cur_table = ttable;
|
||||
|
||||
/* return _SQLExecute(hstmt); */
|
||||
|
@ -436,11 +436,6 @@ void mdb_sql_reset(MdbSQL *sql)
|
||||
sql->cur_table = NULL;
|
||||
}
|
||||
|
||||
if (sql->kludge_ttable_pg) {
|
||||
g_free(sql->kludge_ttable_pg);
|
||||
sql->kludge_ttable_pg = NULL;
|
||||
}
|
||||
|
||||
/* Reset columns */
|
||||
g_ptr_array_foreach(sql->columns, mdb_sql_free_column, NULL);
|
||||
g_ptr_array_free(sql->columns, TRUE);
|
||||
@ -511,11 +506,6 @@ void mdb_sql_listtables(MdbSQL *sql)
|
||||
ttable = mdb_create_temp_table(mdb, "#listtables");
|
||||
mdb_sql_add_temp_col(sql, ttable, 0, "Tables", MDB_TEXT, 30, 0);
|
||||
|
||||
/* blank out the pg_buf */
|
||||
new_pg = mdb_new_data_pg(ttable->entry);
|
||||
memcpy(mdb->pg_buf, new_pg, mdb->fmt->pg_size);
|
||||
g_free(new_pg);
|
||||
|
||||
/* loop over each entry in the catalog */
|
||||
for (i=0; i < mdb->num_catalog; i++) {
|
||||
entry = g_ptr_array_index (mdb->catalog, i);
|
||||
@ -530,7 +520,6 @@ void mdb_sql_listtables(MdbSQL *sql)
|
||||
ttable->num_rows++;
|
||||
}
|
||||
}
|
||||
sql->kludge_ttable_pg = g_memdup(mdb->pg_buf, mdb->fmt->pg_size);
|
||||
sql->cur_table = ttable;
|
||||
|
||||
}
|
||||
@ -586,11 +575,6 @@ void mdb_sql_describe_table(MdbSQL *sql)
|
||||
mdb_sql_add_temp_col(sql, ttable, 1, "Type", MDB_TEXT, 20, 0);
|
||||
mdb_sql_add_temp_col(sql, ttable, 2, "Size", MDB_TEXT, 10, 0);
|
||||
|
||||
/* blank out the pg_buf */
|
||||
new_pg = mdb_new_data_pg(ttable->entry);
|
||||
memcpy(mdb->pg_buf, new_pg, mdb->fmt->pg_size);
|
||||
g_free(new_pg);
|
||||
|
||||
for (i=0;i<table->num_cols;i++) {
|
||||
|
||||
col = g_ptr_array_index(table->columns,i);
|
||||
@ -612,7 +596,6 @@ void mdb_sql_describe_table(MdbSQL *sql)
|
||||
|
||||
/* the column and table names are no good now */
|
||||
//mdb_sql_reset(sql);
|
||||
sql->kludge_ttable_pg = g_memdup(mdb->pg_buf, mdb->fmt->pg_size);
|
||||
sql->cur_table = ttable;
|
||||
}
|
||||
|
||||
@ -755,28 +738,13 @@ mdb_sql_bind_all(MdbSQL *sql)
|
||||
}
|
||||
}
|
||||
/*
|
||||
* mdb_sql_fetch_row should be called instead of mdb_fetch_row when there may be
|
||||
* work tables involved (currently implemented as kludge_ttable_pg)
|
||||
* mdb_sql_fetch_row is now just a wrapper around mdb_fetch_row.
|
||||
* It is left here only for backward compatibility.
|
||||
*/
|
||||
int
|
||||
mdb_sql_fetch_row(MdbSQL *sql, MdbTableDef *table)
|
||||
{
|
||||
MdbHandle *mdb = table->entry->mdb;
|
||||
MdbFormatConstants *fmt = mdb->fmt;
|
||||
unsigned int rows;
|
||||
|
||||
if (sql->kludge_ttable_pg) {
|
||||
memcpy(mdb->pg_buf, sql->kludge_ttable_pg, fmt->pg_size);
|
||||
|
||||
rows = mdb_pg_get_int16(mdb,fmt->row_count_offset);
|
||||
if (rows > table->cur_row) {
|
||||
mdb_read_row(sql->cur_table, table->cur_row++);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return mdb_fetch_row(table);
|
||||
}
|
||||
return mdb_fetch_row(table);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -321,21 +321,7 @@ dump_results_pp(MdbSQL *sql)
|
||||
fprintf(stdout,"\n");
|
||||
|
||||
/* print each row */
|
||||
/*
|
||||
if (sql->kludge_ttable_pg) {
|
||||
memcpy(mdb->pg_buf, sql->kludge_ttable_pg, fmt->pg_size);
|
||||
rows = mdb_pg_get_int16(mdb,fmt->row_count_offset);
|
||||
for (i = 0; i < rows; i++) {
|
||||
rc = mdb_read_row(sql->cur_table, i);
|
||||
row_count++;
|
||||
for (j=0;j<sql->num_columns;j++) {
|
||||
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||
print_value(sql->bound_values[j],sqlcol->disp_size,!j);
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
}
|
||||
*/
|
||||
while(mdb_sql_fetch_row(sql, sql->cur_table)) {
|
||||
while(mdb_fetch_row(sql->cur_table)) {
|
||||
row_count++;
|
||||
for (j=0;j<sql->num_columns;j++) {
|
||||
sqlcol = g_ptr_array_index(sql->columns,j);
|
||||
|
Loading…
Reference in New Issue
Block a user