/* ** Get another row of the given cursor. */ static int cur_fetch (lua_State *L) { cur_data *cur = getcursor(L); sqlite3_stmt *vm = cur->sql_vm; int res; if (vm == NULL) return 0; res = sqlite3_step(vm); /* no more results? */ if (res == SQLITE_DONE) return finalize(L, cur); if (res != SQLITE_ROW) return finalize(L, cur); if (lua_istable (L, 2)) { int i; const char *opts = luaL_optstring(L, 3, "n"); if (strchr(opts, 'n') != NULL) { /* Copy values to numerical indices */ for (i = 0; i < cur->numcols;) { push_column(L, vm, i); lua_rawseti(L, 2, ++i); } } if (strchr(opts, 'a') != NULL) { /* Copy values to alphanumerical indices */ lua_rawgeti(L, LUA_REGISTRYINDEX, cur->colnames); for (i = 0; i < cur->numcols; i++) { lua_rawgeti(L, -1, i+1); push_column(L, vm, i); lua_rawset (L, 2); } } lua_pushvalue(L, 2); return 1; /* return table */ } else { int i; luaL_checkstack (L, cur->numcols, LUASQL_PREFIX"too many columns"); for (i = 0; i < cur->numcols; ++i) push_column(L, vm, i); return cur->numcols; /* return #numcols values */ } }
/* * mode: 0 = direct, 1 = integer, 2 = alphanumeric */ static int l_sqlite3_row_mode(lua_State * L, int mode) { /* Old code / Just a reminder / To be removed: ** checkargs(L, 1, 2, CHECK_PTR, CHECK_NILTABLE, 0); */ sqlite3_stmt * stmt = checkstmt_stmt(L, 1); int num_columns = sqlite3_data_count(stmt); /* Maybe wrong state, so don't use sqlite3_column_count */ int index; /* XXX Should really be cleaned up... Fixme! */ if (mode == 0) lua_checkstack(L, num_columns); else if (!lua_istable(L, -1)) lua_newtable(L); for (index=0; index<num_columns; index++) switch(mode) { case 0: /* direct mode */ push_column(L, stmt, index); break; case 1: /* integer mode */ push_column(L, stmt, index); lua_rawseti(L, -2, index+1); break; case 2: /* alphanumeric mode */ lua_pushstring(L, sqlite3_column_name(stmt, index)); push_column(L, stmt, index); lua_rawset(L, -3); break; default: report_error(L, "libluasqlite3: Internal error in sqlite3_row_mode"); } if (mode) return 1; else return num_columns; }
/* ** Get another row of the given cursor. */ static int cur_fetch (lua_State *L) { cur_data *cur = (cur_data *) getcursor (L); SQLHSTMT hstmt = cur->hstmt; int ret; SQLRETURN rc = SQLFetch(cur->hstmt); if (rc == SQL_NO_DATA) { lua_pushnil(L); return 1; } else if (error(rc)) return fail(L, hSTMT, hstmt); if (lua_istable (L, 2)) { SQLUSMALLINT i; const char *opts = luaL_optstring (L, 3, "n"); int num = strchr (opts, 'n') != NULL; int alpha = strchr (opts, 'a') != NULL; for (i = 1; i <= cur->numcols; i++) { ret = push_column (L, cur->coltypes, hstmt, i); if (ret) return ret; if (alpha) { lua_rawgeti (L, LUA_REGISTRYINDEX, cur->colnames); lua_rawgeti (L, -1, i); /* gets column name */ lua_pushvalue (L, -3); /* duplicates column value */ lua_rawset (L, 2); /* table[name] = value */ lua_pop (L, 1); /* pops colnames table */ } if (num) lua_rawseti (L, 2, i); else lua_pop (L, 1); /* pops value */ } lua_pushvalue (L, 2); return 1; /* return table */ } else { SQLUSMALLINT i; luaL_checkstack (L, cur->numcols, LUASQL_PREFIX"too many columns"); for (i = 1; i <= cur->numcols; i++) { ret = push_column (L, cur->coltypes, hstmt, i); if (ret) return ret; } return cur->numcols; } }
/* ** Returns a row of data from the query ** Lua Returns: ** list of results or table of results depending on call ** nil and error message otherwise. */ static int cur_fetch (lua_State *L) { ISC_STATUS fetch_stat; int i; cur_data *cur = getcursor(L,1); const char *opts = luaL_optstring (L, 3, "n"); int num = strchr(opts, 'n') != NULL; int alpha = strchr(opts, 'a') != NULL; if ((fetch_stat = isc_dsql_fetch(cur->env->status_vector, &cur->stmt, 1, cur->out_sqlda)) == 0) { if (lua_istable (L, 2)) { /* remove the option string */ lua_settop(L, 2); /* loop through the columns */ for (i = 0; i < cur->out_sqlda->sqld; i++) { push_column(L, i, cur); if( num ) { lua_pushnumber(L, i+1); lua_pushvalue(L, -2); lua_settable(L, 2); } if( alpha ) { lua_pushlstring(L, cur->out_sqlda->sqlvar[i].aliasname, cur->out_sqlda->sqlvar[i].aliasname_length); lua_pushvalue(L, -2); lua_settable(L, 2); } lua_pop(L, 1); } /* returning given table */ return 1; } else { for (i = 0; i < cur->out_sqlda->sqld; i++) push_column(L, i, cur); /* returning a list of values */ return cur->out_sqlda->sqld; } } /* isc_dsql_fetch returns 100 if no more rows remain to be retrieved so this can be ignored */ if (fetch_stat != 100L) return return_db_error(L, cur->env->status_vector); /* last row has been fetched, close cursor */ isc_dsql_free_statement(cur->env->status_vector, &cur->stmt, DSQL_drop); if ( CHECK_DB_ERROR(cur->env->status_vector) ) return return_db_error(L, cur->env->status_vector); /* free the cursor data */ free_cur(cur); cur->closed = 1; /* remove cursor from lock count */ --cur->conn->lock; /* return sucsess */ return 0; }
void test_scored_subexpression() { // Create a database with the default options. auto db = grnxx::open_db(""); // Create a table with the default options. auto table = db->create_table("Table"); constexpr size_t NUM_ROWS = 1 << 16; // Generate random values. grnxx::Array<grnxx::Float> float_values; grnxx::Array<grnxx::Int> ref_values; float_values.resize(NUM_ROWS); ref_values.resize(NUM_ROWS); for (size_t i = 0; i < NUM_ROWS; ++i) { float_values[i] = grnxx::Float(1.0 * rng() / rng.max()); // ref_values[i] = mersenne_twister() % NUM_ROWS; ref_values[i] = grnxx::Int(0); } // Create columns for Float and Int values. auto float_column = table->create_column("Float", GRNXX_FLOAT); grnxx::ColumnOptions options; options.reference_table_name = "Table"; auto ref_column = table->create_column("Ref", GRNXX_INT, options); // Store generated values into columns. for (size_t i = 0; i < NUM_ROWS; ++i) { grnxx::Int row_id = table->insert_row(); assert(row_id.match(grnxx::Int(i))); float_column->set(row_id, float_values[i]); } for (size_t i = 0; i < NUM_ROWS; ++i) { ref_column->set(grnxx::Int(i), ref_values[i]); } // Generate a list of records. grnxx::Array<grnxx::Record> records; auto cursor = table->create_cursor(); assert(cursor->read_all(&records) == table->num_rows()); // Set scores (Float). auto builder = grnxx::ExpressionBuilder::create(table); builder->push_column("Float"); auto expression = builder->release(); expression->adjust(&records); // Test an expression (Ref.(_score > 0.5)). builder->push_column("Ref"); builder->begin_subexpression(); builder->push_score(); builder->push_constant(grnxx::Float(0.5)); builder->push_operator(GRNXX_GREATER); builder->end_subexpression(); expression = builder->release(); expression->filter(&records); size_t count = 0; for (size_t i = 0; i < NUM_ROWS; ++i) { if (float_values[i].raw() > 0.5) { assert(records[count].row_id.match(grnxx::Int(i))); ++count; } } assert(records.size() == count); }