← Back to team overview

maria-developers team mailing list archive

Re: custom storage backend rnd_next() implementation and caching questions

 

Hi, Andras!

On Jan 30, Andras Szabo wrote:
> Hi Everyone,
> 
> I am developing a custom mariadb storage backend which is intended to
> give filesystem related information via mariadb tables.
> For example one could tell:
> CREATE TEMPORARY TABLE IF NOT EXISTS `/var/log` ENGINE=fsview;
> which would create a table (using the assisted discovery method) with the following schema:

Cool!

> 1. I am having trouble implementing rnd_next() in the backend:
> 
> int ha_fsview::rnd_next(uchar *buf) {
>     DBUG_ENTER(__PRETTY_FUNCTION__);
>     if (!dirp) {
>         DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
>     }
>     if (struct dirent* entry = readdir(dirp)) {
>         uchar *pos = buf;
>         *pos = 0;
>         ++pos;
>         // file name (1bytes size + str)
>         *pos = strlen(entry->d_name);
>         ++pos;
>         size_t bytes_to_copy = strlen(entry->d_name);
>         memcpy(pos, entry->d_name, bytes_to_copy);
>         pos+=bytes_to_copy;
>         DBUG_PRINT("info", ("fsview filename: %s", entry->d_name));
>         // content (4 bytes size + content ptr)
>         static const std::string fake_content = "hello world";
>         int s = fake_content.size();
>         memcpy(pos, &s, sizeof(s));
>         pos+=sizeof(s);
>         const char* c = fake_content.c_str();
>         memcpy(pos, &c, sizeof(c));
>         pos+=sizeof(c);
>         DBUG_RETURN(0);
>     } else {
>         DBUG_RETURN(HA_ERR_END_OF_FILE);
>     }
> }
> 
> My problem is that filenames (first field) is ok, but i cannot really
> see the expected content “hello world” in the second field. I am
> assuming that i am doing something wrong, but i cannot really find the
> reason. Could somebody help me, please?

This looks correct to me. May be, perhaps. std::string->c_str() isn't
returning the pointer to your static string (but to a some temporary
copy that gets invalidated on return)? I don't know how std::string is
supposed to work in this case.

Anyway it might've been easier to use Field methods than assembling the
row directly. Like

  table->field[0]->store(entry->d_name, strlen(entry->d_name), system_charset_info);
  table->field[1]->store(STRING_WITH_LEN("hello world"), system_charset_info);

> 2. If i am issuing:
> 
>  SELECT * FROM `/var`;
> 
> twice, then the server is not initiating a table scan again on my
> backend (most likely results from the first run are stored in some
> cache). So if filesystem contents are changed between the two
> statements, then it won’t be reflected in the resultset.
> 
>  Of course if i do a:
> 
>  SELECT SQL_NO_CACHE * FROM `/var`;
> 
> then everything is fine, however i would not like to put the burden on
> the user to specify the option to not cache the results.
> 
> My question is whether it’s possible to specify in the storage backend
> that the results from the tables should not be cached.

Yes. See handler::register_query_cache_table().

Regards,
Sergei


Follow ups

References