I am using C MySQL API
int numr=mysql_num_rows(res);
It always returns zero, but in my table there are 4 rows are there. However, I am getting the correct fields count.
what is the problem? Am i doing anything wrong?
Just a guess:
If you use mysql_use_result(), mysql_num_rows() does not return the correct value until all the rows in the result set have been retrieved.
(from the mysql manual)
The only reason to receive a zero from mysql_num_rows(<variable_name>) is because the query did not return anything.
You haven't posted the query here that you run and then assign the result to your res variable so we can't check it.
But try running that exact query in your DB locally through whatever DB management software you use and see if you are able to achieve any results.
If the query is working fine, then it must be the way you're running the query in C, otherwise your query is broken.
Maybe post up a bit more of your code from C where you make the query and then run it.
Thanks
If you just want to count the number of rows in a table, say
SELECT COUNT(*) FROM table_name
You will get back a single column in a single row containing the answer.
I too have this problem. But I noticed that mysql.h defines mysql_num_rows() to return a "my_ulonglong". Also in the header file you will see that there is a type def for my_ulonglong. On my system size of a my_ulonglong is 8 bytes. When we try to print this out or cast this to an int we probably get the first four bytes which are zero. However I printed out the eight bytes at the address of my_ulonglong variable and it prints all zeros. So I think this function just doesn't work.
`my_ulonglong numOfRows;
MYSQL *resource;
MYSQL *connection;
mysql_query(connection,"SELECT * FROM channels");
resource = mysql_use_result(connection);
numChannels = mysql_num_rows(resource);
printf("Writing numChannels: %lu\n", numChannels); // returns 0
printf("Size of numChannels is %d.\n", sizeof(numChannels)); // returns 8
// however
unsigned char * tempChar;
tempChar = (unsigned char *) &numChannels;
for (i=0; i< (int) sizeof(numChannels); ++i) {
printf("%02x", (unsigned int) *tempChar++);
}
printf("\n");
// returned 0000000000000000 so I think its a bug.
//mysql.h typedef for my_ulonglong and function mysql_num_rows()
#ifndef _global_h
#if defined(NO_CLIENT_LONG_LONG)
typedef unsigned long my_ulonglong;
#elif defined (__WIN__)
typedef unsigned __int64 my_ulonglong;
#else
typedef unsigned long long my_ulonglong;
#endif
#endif
my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res);
`
Related
I am trying to add 2 char arrays in cuda, but nothing is working.
I tried to use:
char temp[32];
strcpy(temp, my_array);
strcat(temp, my_array_2);
When I used this in kernel - I am getting error : calling a __host__ function("strcpy") from a __global__ function("Process") is not allowed
After this, I tried to use these functions in host, not in kernel - no error,but after addition I am getting strange symbols like ĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶĶ.
So, how I can add two ( or more ) char arrays in CUDA ?
So, how I can add two ( or more ) char arrays in CUDA ?
write your own functions:
__device__ char * my_strcpy(char *dest, const char *src){
int i = 0;
do {
dest[i] = src[i];}
while (src[i++] != 0);
return dest;
}
__device__ char * my_strcat(char *dest, const char *src){
int i = 0;
while (dest[i] != 0) i++;
my_strcpy(dest+i, src);
return dest;
}
And while we're at it, here is strcmp
As the error message explains, you are trying to call host functions ("CPU functions") from a global kernel ("GPU function"). Within a global kernel you only have access to functions provided by the CUDA runtime API, which doesn't include the C standard library (where strcpy and strcat are defined).
You have to create your own str* functions according to what you want to do. Do you want to concatenate an array of chars in parallel, or do it serially in each thread?
I'm trying to store results taken from a MySQL query into an array of structs. I can't seem to get the types to work though, and I've found the MySQL documentation difficult to sort through.
My struct is:
struct login_session
{
char* user[10];
time_t time;
int length;
};
And the loop where I'm trying to get the data is:
while ( (row = mysql_fetch_row(res)) != NULL ) {
strcpy(records[cnt].user, &row[0]);
cnt++;
}
No matter what I try though I constantly get the error:
test.c:45: warning: passing argument 1 of ‘strcpy’ from incompatible pointer type
/usr/include/string.h:128: note: expected ‘char * __restrict__’ but argument is of type ‘char **’
test.c:45: warning: passing argument 2 of ‘strcpy’ from incompatible pointer type
/usr/include/string.h:128: note: expected ‘const char * __restrict__’ but argument is of type ‘MYSQL_ROW’
Any pointers?
Multiple problems, all related to pointers and arrays, I recommend you do some reading.
First, char * user[10] is defining an array of 10 char * values, not an array of char, which is was I suspect you want. The warning even says as much, strcpy() expects a char *, the user field on its own is seen as a char **.
Second, you're one & away from what you want in the second argument.
Copied from mysql.h header:
typedef char **MYSQL_ROW; /* return data as array of strings */
A MYSQL_ROW is an array of char arrays. Using [] does a dereference, so you dereference down to a char * which is what strcpy() takes, but then you take the address of it using &.
Your code should look more like this:
struct login_session
{
char user[10];
time_t time;
int length;
};
while ( (row = mysql_fetch_row(res)) != NULL ) {
strcpy(records[cnt].user, row[0]);
cnt++;
}
I don't know what guarantees you have about the data coming from mysql, but if you can't be absolutely sure that the rows are <= 10 characters long and null ('\0') terminated, you should use strncpy() to avoid any possibility of overflowing the user array.
Let us assume that we have the following strings that we need to store in a CUDA array.
"hi there"
"this is"
"who is"
How do we declare a array on the GPU to do this. I tried using C++ strings but it does not work.
Probably the best way to do this is to use structure that is similar to common compressed sparse matrix formats. Store the character data packed into a single piece of linear memory, then use a separate integer array to store the starting indices, and perhaps a third array to store the string lengths. The storage overhead of the latter might be more efficient that storing a string termination byte for every entry in the data and trying to parse for the terminator inside the GPU code.
So you might have something like this:
struct gpuStringArray {
unsigned int * pos;
unsigned int * length; // could be a smaller type if strings are short
char4 * data; // 32 bit data type will improve memory throughput, could be 8 bit
}
Note I used a char4 type for the string data; the vector type will give better memory throughput, but it will mean strings need to be aligned/suitably padded to 4 byte boundaries. That may or may not be a problem depending on what a typical real string looks like in your application. Also, the type of the (optional) length parameter should probably be chosen to reflect the maximum admissible string length. If you have a lot of very short strings, it might be worth using an 8 or 16 bit unsigned type for the lengths to save memory.
A really simplistic code to compare strings stored this way in the style of strcmp might look something like this:
__device__ __host__
int cmp4(const char4 & c1, const char4 & c2)
{
int result;
result = c1.x - c2.x; if (result !=0) return result;
result = c1.y - c2.y; if (result !=0) return result;
result = c1.z - c2.z; if (result !=0) return result;
result = c1.w - c2.w; if (result !=0) return result;
return 0;
}
__device__ __host__
int strncmp4(const char4 * s1, const char4 * s2, const unsigned int nwords)
{
for(unsigned int i=0; i<nwords; i++) {
int result = cmp4(s1[i], s2[i]);
if (result != 0) return result;
}
return 0;
}
__global__
void tkernel(const struct gpuStringArray a, const gpuStringArray b, int * result)
{
int idx = threadIdx.x + blockIdx.x * blockDim.x;
char4 * s1 = a.data + a.pos[idx];
char4 * s2 = b.data + b.pos[idx];
unsigned int slen = min(a.length[idx], b.length[idx]);
result[idx] = strncmp4(s1, s2, slen);
}
[disclaimer: never compiled, never tested, no warranty real or implied, use at your own risk]
There are some corner cases and assumptions in this which might catch you out depending on exactly what the real strings in your code look like, but I will leave those as an exercise to the reader to resolve. You should be able to adapt and expand this into whatever it is you are trying to do.
You have to use C-style character strings char *str. Searching for "CUDA string" on google would have given you this CUDA "Hello World" example as first hit: http://computer-graphics.se/hello-world-for-cuda.html
There you can see how to use char*-strings in CUDA. Be aware that standard C-functions like strcpy or strcmp are not available in CUDA!
If you want an array of strings, you just have to use char** (as in C/C++). As for strcmp and similar functions, it highly depends on what you want to do. CUDA is not really well suited for string operations, maybe it would help if you would provide a little more detail about what you want to do.
I'm writing C program to access database.
I recently switch from sqlite to mysql.
I'm not familiar with mysql c api, so I need help converting some code.
Below example is executing sql statement with parameter.
sqlite:
char *zSQL = sqlite3_mprintf("SELECT price FROM warehouse WHERE p_ID='%q'", input_value);
sqlite3_prepare_v2(handle,zSQL,-1,&stmt,0);
my attempt in mysql:
char zSQL[60] = {'\0'};
int n = 0;
n = sprintf(zSQL, "SELECT price FROM warehouse WHERE p_ID='%s'", input_value);
mysql_real_query(conn, zSQL, n);
Another example is parsing result of sql statement to variable
sqlite:
double price_value = 0;
if (sqlite3_step (stmt) == SQLITE_ROW) {
price_value = sqlite3_column_double (stmt, 0);
}
mysql:
MYSQL_ROW row;
while ((row = mysql_fetch_row(result)))
{
price_value = atof(row[0]);
}
While the code in mysql works for me, but I feel like I'm not utilizing the API enough.
Is there any function in mysql c api which has the same functionality as sqlite3_mprintf() and sqlite3_column_double() ?
Edit:
My attempt on mysql_real_escape_string():
ulong in_length = strlen(input_value);
char input_esc[(2 * in_length)+1];
mysql_real_escape_string(conn, input_esc, input_value, in_length);
char sql_stmnt[56] = {'\0'};
n = sprintf(zSQL, "SELECT price FROM warehouse WHERE p_ID='%s'", input_esc);
mysql_real_query(conn, sql_stmnt, n);
For your first exampe, the short answer is no, you have to do it yourself, see http://dev.mysql.com/doc/refman/5.5/en/mysql-real-escape-string.html
unsigned long mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned long length)
The second one, yes, that's the way to go, with some additional check that row[0] is indeed of type double.
Alternatively, you can use the prepared statement API which works quite similar to the one in sqlite3. The key is you provide buffers of type MYSQL_BIND and then either bind the inputs to it, or have mysql binding output values there.
Prepared statement documentation: http://dev.mysql.com/doc/refman/5.5/en/c-api-prepared-statement-data-structures.html
I am using the MySQL C API to query the database and I have the results stored in MYSQL_ROW types. I am able to print the results to the console with
printf("%s", row[0]);
however, according to the MySQL C API documentation, I cannot use them as null-terminated strings.
At the bottom of the function overview, they say I can "extract" the information with mysql_store_result() or mysql_use_result(). However, I am still confused as to how this is done.
Ideally, I want to use the results as a string so I can do stuff like strcmp, but otherwise I definitely need to use the information somehow with those two functions.
Can somebody show me an example of how to do this?
Basically, you call mysql_store_result() or mysql_use_result() to access the result set, the former loads all the rows into memory on the client side, the latter accesses rows one at a time from the server. If you use mysql_use_result(), you need to call mysql_fetch_row() to access each row until the function returns NULL. Each successful call to mysql_fetch_row() will return a MYSQL_ROW which you can use to access the individual field values.
Since the fields are not nul-terminated, you need to use mysql_fetch_lengths() to get the lengths of each of the fields so that you can copy them somewhere else via memcpy, etc.
Since the field values are not nul-terminated you will need to add your own NUL character when you make the copy if you want to use it as a string. Be aware that the field values may contain binary data, so if you do treat it as a string, functions that expect a C string will stop processing data if it encounters a nul-character in the data.
Here is an example from the documentation that should help you put all this together:
MYSQL_ROW row;
unsigned int num_fields;
unsigned int i;
num_fields = mysql_num_fields(result);
while ((row = mysql_fetch_row(result)))
{
unsigned long *lengths;
lengths = mysql_fetch_lengths(result);
for(i = 0; i < num_fields; i++)
{
printf("[%.*s] ", (int) lengths[i],
row[i] ? row[i] : "NULL");
}
printf("\n");
}