static QSeq* constructQSeq( BuildSQLState* state, dbi_result result ) { int id = dbi_result_get_int_idx( result, 1 ); int parent_query_id = dbi_result_get_int_idx( result, 2 ); int seq_no = dbi_result_get_int_idx( result, 3 ); int child_query_id = dbi_result_get_int_idx( result, 4 ); StoredQ* child_query = getStoredQuery( state, child_query_id ); if( !child_query ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to load child query # %d for parent query %d", child_query_id, parent_query_id )); state->error = 1; return NULL; } // Allocate a QSeq; from the free list if possible, from the heap if necessary QSeq* seq = NULL; if( free_qseq_list ) { seq = free_qseq_list; free_qseq_list = free_qseq_list->next; } else seq = safe_malloc( sizeof( QSeq )); seq->next = NULL; seq->id = id; seq->parent_query_id = parent_query_id; seq->seq_no = seq_no; seq->child_query = child_query; return seq; }
static OrderItem* constructOrderItem( BuildSQLState* state, dbi_result result ) { int id = dbi_result_get_int_idx( result, 1 ); int stored_query_id = dbi_result_get_int_idx( result, 2 ); int seq_no = dbi_result_get_int_idx( result, 3 ); int expression_id = dbi_result_get_int_idx( result, 4 ); // Allocate a SelectItem: from the free list if possible, from the heap if necessary // Construct an Expression Expression* expression = getExpression( state, expression_id ); if( !expression ) { osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to fetch ORDER BY expression for id = %d", expression_id )); return NULL; }; // Allocate an OrderItem; from the free list if possible, or from the heap if necessary. OrderItem* ord; if( free_order_item_list ) { ord = free_order_item_list; free_order_item_list = free_order_item_list->next; } else ord = safe_malloc( sizeof( OrderItem )); ord->next = NULL; ord->id = id; ord->stored_query_id = stored_query_id; ord->seq_no = seq_no; ord->expression = expression; return ord; }
static double rrd_fetch_dbi_double(dbi_result *result,int idx) { char *ptmp=""; double value=DNAN; /* get the attributes for this filed */ unsigned int attr=dbi_result_get_field_attribs_idx(result,idx); unsigned int type=dbi_result_get_field_type_idx(result,idx); /* return NAN if NULL */ if(dbi_result_field_is_null_idx(result,idx)) { return DNAN; } /* do some conversions */ switch (type) { case DBI_TYPE_STRING: ptmp=(char*)dbi_result_get_string_idx(result,idx); value=strtod(ptmp,NULL); break; case DBI_TYPE_INTEGER: if (attr & DBI_INTEGER_SIZE1) { value=dbi_result_get_char_idx(result,idx); } else if (attr & DBI_INTEGER_SIZE2) { value=dbi_result_get_short_idx(result,idx); } else if (attr & DBI_INTEGER_SIZE3) { value=dbi_result_get_int_idx(result,idx); } else if (attr & DBI_INTEGER_SIZE4) { value=dbi_result_get_int_idx(result,idx); } else if (attr & DBI_INTEGER_SIZE8) { value=dbi_result_get_longlong_idx(result,idx); } else { value=DNAN; if (getenv("RRDDEBUGSQL")) { fprintf(stderr,"RRDDEBUGSQL: %li: column %i unsupported attribute flags %i for type INTEGER\n",time(NULL),idx,attr ); } } break; case DBI_TYPE_DECIMAL: if (attr & DBI_DECIMAL_SIZE4) { value=dbi_result_get_float_idx(result,idx); } else if (attr & DBI_DECIMAL_SIZE8) { value=dbi_result_get_double_idx(result,idx); } else { value=DNAN; if (getenv("RRDDEBUGSQL")) { fprintf(stderr,"RRDDEBUGSQL: %li: column %i unsupported attribute flags %i for type DECIMAL\n",time(NULL),idx,attr ); } } break; case DBI_TYPE_BINARY: attr=dbi_result_get_field_length_idx(result,idx); ptmp=(char*)dbi_result_get_binary_copy_idx(result,idx); ptmp[attr-1]=0; /* check for "known" libdbi error */ if (strncmp("ERROR",ptmp,5)==0) { if (!getenv("RRD_NO_LIBDBI_BUG_WARNING")) { fprintf(stderr,"rrdtool_fetch_libDBI: you have possibly triggered a bug in libDBI by using a (TINY,MEDIUM,LONG) TEXT field with mysql\n this may trigger a core dump in at least one version of libdbi\n if you are not touched by this bug and you find this message annoying\n please set the environment-variable RRD_NO_LIBDBI_BUG_WARNING to ignore this message\n"); } } /* convert to number */ value=strtod(ptmp,NULL); /* free pointer */ free(ptmp); break; case DBI_TYPE_DATETIME: value=dbi_result_get_datetime_idx(result,idx); break; default: if (getenv("RRDDEBUGSQL")) { fprintf(stderr,"RRDDEBUGSQL: %li: column %i unsupported type: %i with attribute %i\n",time(NULL),idx,type,attr ); } value=DNAN; break; } return value; }
long long SMSDDBI_GetNumber(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field) { unsigned int type; field++; type = dbi_result_get_field_type_idx(res->dbi, field); switch (type) { case DBI_TYPE_INTEGER: type = dbi_result_get_field_attribs_idx(res->dbi, field); if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE1) { return dbi_result_get_int_idx(res->dbi, field); } else if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE2) { return dbi_result_get_int_idx(res->dbi, field); } else if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE3) { return dbi_result_get_int_idx(res->dbi, field); } else if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE4) { return dbi_result_get_int_idx(res->dbi, field); } else if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE8) { return dbi_result_get_longlong_idx(res->dbi, field); } SMSD_Log(DEBUG_ERROR, Config, "Wrong integer field subtype from DBI: %d", type); return -1; case DBI_TYPE_DECIMAL: type = dbi_result_get_field_attribs_idx(res->dbi, field); if ((type & DBI_DECIMAL_SIZEMASK) == DBI_DECIMAL_SIZE4) { return dbi_result_get_int_idx(res->dbi, field); } else if ((type & DBI_DECIMAL_SIZEMASK) == DBI_DECIMAL_SIZE8) { return dbi_result_get_longlong_idx(res->dbi, field); } SMSD_Log(DEBUG_ERROR, Config, "Wrong decimal field subtype from DBI: %d", type); return -1; #ifdef DBI_TYPE_XDECIMAL case DBI_TYPE_XDECIMAL: return dbi_result_get_as_longlong_idx(res->dbi, field); #endif default: SMSD_Log(DEBUG_ERROR, Config, "Wrong field type for number (not INTEGER nor DECIMAL) from DBI: %d", type); return -1; } }
static SelectItem* constructSelectItem( BuildSQLState* state, dbi_result result ) { // Get the column values int id = dbi_result_get_int_idx( result, 1 ); int stored_query_id = dbi_result_get_int_idx( result, 2 ); int seq_no = dbi_result_get_int_idx( result, 3 ); int expression_id = dbi_result_get_int_idx( result, 4 ); const char* column_alias = dbi_result_get_string_idx( result, 5 ); int grouped_by = oils_result_get_bool_idx( result, 6 ); // Construct an Expression Expression* expression = getExpression( state, expression_id ); if( !expression ) { osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to fetch expression for id = %d", expression_id )); return NULL; }; // Allocate a SelectItem: from the free list if possible, from the heap if necessary SelectItem* sel; if( free_select_item_list ) { sel = free_select_item_list; free_select_item_list = free_select_item_list->next; } else sel = safe_malloc( sizeof( SelectItem ) ); sel->next = NULL; sel->id = id; sel->stored_query_id = stored_query_id; sel->seq_no = seq_no; sel->expression = expression; sel->column_alias = column_alias ? strdup( column_alias ) : NULL; sel->grouped_by = grouped_by; return sel; }
/** * SQL callback. Return an integer from a query * * @param return_integer integer pointer cast to void* which holds the integer to be returned * @param result dbi_result pointer * @return 0 (always, due to SQLite policy, may change in the future) */ int tagsistant_return_integer(void *return_integer, dbi_result result) { uint32_t *buffer = (uint32_t *) return_integer; *buffer = 0; unsigned int type = dbi_result_get_field_type_idx(result, 1); if (type == DBI_TYPE_INTEGER) { unsigned int size = dbi_result_get_field_attribs_idx(result, 1); unsigned int is_unsigned = size & DBI_INTEGER_UNSIGNED; size = size & DBI_INTEGER_SIZEMASK; switch (size) { case DBI_INTEGER_SIZE8: if (is_unsigned) *buffer = dbi_result_get_ulonglong_idx(result, 1); else *buffer = dbi_result_get_longlong_idx(result, 1); break; case DBI_INTEGER_SIZE4: case DBI_INTEGER_SIZE3: if (is_unsigned) *buffer = dbi_result_get_uint_idx(result, 1); else *buffer = dbi_result_get_int_idx(result, 1); break; case DBI_INTEGER_SIZE2: if (is_unsigned) *buffer = dbi_result_get_ushort_idx(result, 1); else *buffer = dbi_result_get_short_idx(result, 1); break; case DBI_INTEGER_SIZE1: if (is_unsigned) *buffer = dbi_result_get_uchar_idx(result, 1); else *buffer = dbi_result_get_char_idx(result, 1); break; } } else if (type == DBI_TYPE_DECIMAL) { return (0); } else if (type == DBI_TYPE_STRING) { const gchar *int_string = dbi_result_get_string_idx(result, 1); *buffer = atoi(int_string); dbg('s', LOG_INFO, "tagsistant_return_integer called on non integer field"); } dbg('s', LOG_INFO, "Returning integer: %d", *buffer); return (0); }
int dbiw_res_get_int64_ndx(db_wrap_result * self, unsigned int ndx, int64_t * val) { RES_DECL(DB_WRAP_E_BAD_ARG); if (! val) return DB_WRAP_E_BAD_ARG; unsigned int const realIdx = ndx+1; //FIXME("Consolidate the duplicate code in get_int32_ndx() and here."); #if 1 /** See this thread: http://www.mail-archive.com/[email protected]/msg00126.html */ unsigned int const a = dbi_result_get_field_attrib_idx (dbires, realIdx, 0, 0xff) /* i can't find one bit of useful docs/examples for this function, so i'm kind of guessing here. */ ; /* MARKER("Attribute return=0x%x/%u\n",a, a); */ /*assert(0);*/ if (DBI_ATTRIBUTE_ERROR == a) { return DB_WRAP_E_CHECK_DB_ERROR; } else if (DBI_INTEGER_SIZE1 & a) { /* MARKER("SIZE1\n"); */ *val = (a & DBI_DECIMAL_UNSIGNED) ? dbi_result_get_uchar_idx(dbires, realIdx) : dbi_result_get_char_idx(dbires, realIdx) ; } else if (DBI_INTEGER_SIZE2 & a) { /* MARKER("SIZE2\n"); */ *val = (a & DBI_DECIMAL_UNSIGNED) ? dbi_result_get_ushort_idx(dbires, realIdx) : dbi_result_get_short_idx(dbires, realIdx) ; } else if (DBI_INTEGER_SIZE4 & a) { /*MARKER("SIZE4\n");*/ *val = (a & DBI_DECIMAL_UNSIGNED) ? dbi_result_get_uint_idx(dbires, realIdx) : dbi_result_get_int_idx(dbires, realIdx) ; } else if (DBI_INTEGER_SIZE8 & a) { /* MARKER("SIZE8\n"); */ *val = (a & DBI_DECIMAL_UNSIGNED) ? dbi_result_get_ulonglong_idx(dbires, realIdx) : dbi_result_get_longlong_idx(dbires, realIdx) ; } else { /** libdbi Sqlite driver returns 0 for attributes for the case of SELECT COUNT(*). i have no workaround for this :(. */ return DB_WRAP_E_UNKNOWN_ERROR; } #else //*val = dbi_result_get_int_idx(dbires, realIdx); //MARKER("val as int=%"PRIi64"\n",*val); //if (!*val) *val = dbi_result_get_longlong_idx(dbires, realIdx); //MARKER("val as longlong=%"PRIi64"\n",*val); #endif return 0; }
int dbiw_res_get_int32_ndx(db_wrap_result * self, unsigned int ndx, int32_t * val) { RES_DECL(DB_WRAP_E_BAD_ARG); if (! val) return DB_WRAP_E_BAD_ARG; unsigned int const realIdx = ndx+1; #if 1 /** See this thread: http://www.mail-archive.com/[email protected]/msg00126.html */ unsigned int const a = dbi_result_get_field_attrib_idx (dbires, realIdx, 0/*DBI_INTEGER_UNSIGNED*/, 0xff/*DBI_INTEGER_SIZE8*/) /* i can't find one bit of useful docs/examples for this function, so i'm kind of guessing here. */ ; //MARKER("Attribute return=0x%x/%u\n",a, a); /*assert(0);*/ /** See this thread: http://www.mail-archive.com/[email protected]/msg00126.html */ if (DBI_ATTRIBUTE_ERROR == a) { return DB_WRAP_E_CHECK_DB_ERROR; } #if 0 else if (0 == a) { /* HORRIBLE KLUDGE for sqlite driver! But after testing, NONE of these return the value i'm expecting! */ *val = dbi_result_get_short_idx(dbires, realIdx); if (!*val) *val = dbi_result_get_ushort_idx( dbires, realIdx ); if (!*val) *val = dbi_result_get_int_idx( dbires, realIdx ); if (!*val) *val = dbi_result_get_uint_idx( dbires, realIdx ); if (!*val) *val = dbi_result_get_longlong_idx( dbires, realIdx ); if (!*val) *val = dbi_result_get_ulonglong_idx( dbires, realIdx ); //if (!*val) *val = dbi_result_get_double_idx( dbires, realIdx ); } #endif else if (DBI_INTEGER_SIZE1 & a) { /* MARKER("SIZE1\n"); */ *val = (a & DBI_DECIMAL_UNSIGNED) ? dbi_result_get_uchar_idx(dbires, realIdx) : dbi_result_get_char_idx(dbires, realIdx) ; } else if (DBI_INTEGER_SIZE2 & a) { /* MARKER("SIZE2\n"); */ *val = (a & DBI_DECIMAL_UNSIGNED) ? dbi_result_get_ushort_idx(dbires, realIdx) : dbi_result_get_short_idx(dbires, realIdx) ; } else if (DBI_INTEGER_SIZE4 & a) { /* MARKER("SIZE4\n"); */ *val = (a & DBI_DECIMAL_UNSIGNED) ? dbi_result_get_uint_idx(dbires, realIdx) : dbi_result_get_int_idx(dbires, realIdx) ; } else if (DBI_INTEGER_SIZE8 & a) { /* MARKER("SIZE8\n"); */ *val = (a & DBI_DECIMAL_UNSIGNED) ? dbi_result_get_ulonglong_idx(dbires, realIdx) : dbi_result_get_longlong_idx(dbires, realIdx) ; } else { /** libdbi Sqlite driver returns 0 for attributes for the case of SELECT COUNT(*). i have no workaround for this :(. */ return DB_WRAP_E_UNKNOWN_ERROR; } #else *val = dbi_result_get_int_idx(dbires, realIdx); #endif return 0; }
//******************************************************************* // retrieve the definitions + status // get it from the cache. if there but too old: delete // If a probe definition does not exist, it will be created. // in case of mysql-has-gone-away type errors, we keep on running, // it will be caught later-on. //******************************************************************* void *bb_cpu_get_def(trx *t, int create) { struct probe_def *def; struct bb_cpu_result *res = (struct bb_cpu_result *)t->res; dbi_result result; time_t now = time(NULL); if (res->color != STAT_PURPLE && res->server == 0) { // first we find the serverid, this will be used to find the probe definition in the hashtable result = db_query(t->probe->db, 0, query_server_by_name, res->hostname, res->hostname, res->hostname, res->hostname, res->hostname); if (!result) { return(NULL); } if (dbi_result_next_row(result)) { res->server = dbi_result_get_int_idx(result, 0); } else { LOG(LOG_NOTICE, "%s:%u@%s: server %s not found", res->realm, res->stattime, t->fromhost, res->hostname); dbi_result_free(result); return(NULL); } dbi_result_free(result); } // look in the cache for the def def = g_hash_table_lookup(t->probe->cache, &res->server); if (def && def->stamp < now - (120 + uw_rand(240))) { // older then 2 - 6 minutes? g_hash_table_remove(t->probe->cache, &res->server); def = NULL; } // if not there retrieve from database and insert in hash if (def == NULL) { def = g_malloc0(t->probe->def_size); def->stamp = time(NULL); def->server = res->server; def->pgroup = 1; strcpy(def->hide, "no"); // first find the definition based on the serverid result = db_query(t->probe->db, 0, "select id, yellow, red, contact, hide, email, sms, delay " "from pr_%s_def where server = '%u'", res->name, res->server); if (!result) { g_free(def); return(NULL); } if (dbi_result_get_numrows(result) == 0) { // DEF RECORD NOT FOUND char sequence[40]; // no def record found? Create one. dbi_result_free(result); result = db_query(t->probe->db, 0, "insert into pr_%s_def (server, description) values ('%u', '%s')", res->name, res->server, res->hostname); dbi_result_free(result); sprintf(sequence, "pr_%s_def_id_seq", res->name); def->probeid = dbi_conn_sequence_last(t->probe->db, sequence); LOG(LOG_NOTICE, "%s:%u@%s: pr_%s_def created for %s, id = %u", res->realm, res->stattime, t->fromhost, res->name, res->hostname, def->probeid); result = db_query(t->probe->db, 0, "select id, yellow, red, contact, hide, email, sms, delay " "from pr_%s_def where id = '%u'", res->name, def->probeid); } if (!dbi_result_next_row(result)) { LOG(LOG_NOTICE, "%s:%u@%s: no pr_%s_def found for server %u - skipped", res->realm, res->stattime, t->fromhost, res->name, res->server); dbi_result_free(result); g_free(def); return(NULL); } def->probeid = dbi_result_get_int(result, "id"); def->yellow = dbi_result_get_float(result, "yellow"); def->red = dbi_result_get_float(result, "red"); def->contact = dbi_result_get_int(result, "contact"); strcpy(def->hide, dbi_result_get_string_default(result, "hide", "no")); strcpy(def->email, dbi_result_get_string_default(result, "email", "")); strcpy(def->sms, dbi_result_get_string_default(result, "sms", "")); def->delay = dbi_result_get_int(result, "delay"); dbi_result_free(result); result = db_query(t->probe->db, 0, "select color " "from pr_status " "where class = '%u' and probe = '%u'", t->probe->class, def->probeid); if (result) { if (dbi_result_next_row(result)) { def->color = dbi_result_get_int(result, "color"); } else { LOG(LOG_NOTICE, "%s:%u@%s: pr_status record for %s id %u not found", res->realm, res->stattime, t->fromhost, res->name, def->probeid); } dbi_result_free(result); } if (!def->color) def->color = res->color; result = db_query(t->probe->db, 0, "select stattime from pr_%s_raw use index(probstat) " "where probe = '%u' order by stattime desc limit 1", res->name, def->probeid); if (result) { if (dbi_result_next_row(result)) { def->newest = dbi_result_get_int(result, "stattime"); } dbi_result_free(result); } g_hash_table_insert(t->probe->cache, guintdup(def->server), def); }
unsigned int dbi_result_get_uint_idx(dbi_result Result, unsigned int fieldidx) { return (unsigned int)dbi_result_get_int_idx(Result, fieldidx); }
int dbi_result_get_long_idx(dbi_result Result, unsigned int fieldidx) { return dbi_result_get_int_idx(Result, fieldidx); }
static Expression* constructExpression( BuildSQLState* state, dbi_result result ) { int id = dbi_result_get_int_idx( result, 1 ); const char* type_str = dbi_result_get_string_idx( result, 2 ); ExprType type; if( !strcmp( type_str, "xbet" )) type = EXP_BETWEEN; else if( !strcmp( type_str, "xbool" )) type = EXP_BOOL; else if( !strcmp( type_str, "xcase" )) type = EXP_CASE; else if( !strcmp( type_str, "xcast" )) type = EXP_CAST; else if( !strcmp( type_str, "xcol" )) type = EXP_COLUMN; else if( !strcmp( type_str, "xex" )) type = EXP_EXIST; else if( !strcmp( type_str, "xfld" )) type = EXP_FIELD; else if( !strcmp( type_str, "xfunc" )) type = EXP_FUNCTION; else if( !strcmp( type_str, "xin" )) type = EXP_IN; else if( !strcmp( type_str, "xnbet" )) type = EXP_NOT_BETWEEN; else if( !strcmp( type_str, "xnex" )) type = EXP_NOT_EXIST; else if( !strcmp( type_str, "xnin" )) type = EXP_NOT_IN; else if( !strcmp( type_str, "xnull" )) type = EXP_NULL; else if( !strcmp( type_str, "xnum" )) type = EXP_NUMBER; else if( !strcmp( type_str, "xop" )) type = EXP_OPERATOR; else if( !strcmp( type_str, "xstr" )) type = EXP_STRING; else if( !strcmp( type_str, "xsubq" )) type = EXP_SUBQUERY; else type = EXP_NULL; // shouldn't happen due to database constraint int parenthesize = oils_result_get_bool_idx( result, 3 ); int parent_expr_id; if( dbi_result_field_is_null_idx( result, 4 )) parent_expr_id = -1; else parent_expr_id = dbi_result_get_int_idx( result, 4 ); int seq_no = dbi_result_get_int_idx( result, 5 ); const char* literal = dbi_result_get_string_idx( result, 6 ); const char* table_alias = dbi_result_get_string_idx( result, 7 ); const char* column_name = dbi_result_get_string_idx( result, 8 ); int left_operand_id; if( dbi_result_field_is_null_idx( result, 9 )) left_operand_id = -1; else left_operand_id = dbi_result_get_int_idx( result, 9 ); const char* operator = dbi_result_get_string_idx( result, 10 ); int right_operand_id; if( dbi_result_field_is_null_idx( result, 11 )) right_operand_id = -1; else right_operand_id = dbi_result_get_int_idx( result, 11 ); int function_id; if( dbi_result_field_is_null_idx( result, 12 )) function_id = -1; else function_id = dbi_result_get_int_idx( result, 12 ); int subquery_id; if( dbi_result_field_is_null_idx( result, 13 )) subquery_id = -1; else subquery_id = dbi_result_get_int_idx( result, 13 ); int cast_type_id; if( dbi_result_field_is_null_idx( result, 14 )) cast_type_id = -1; else cast_type_id = dbi_result_get_int_idx( result, 14 ); Expression* left_operand = NULL; Expression* right_operand = NULL; StoredQ* subquery = NULL; if( EXP_OPERATOR == type ) { // Load left and/or right operands if( -1 == left_operand_id && -1 == right_operand_id ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Expression # %d is an operator with no operands", id )); state->error = 1; return NULL; } if( left_operand_id != -1 ) { left_operand = getExpression( state, left_operand_id ); if( !left_operand ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to get left operand in expression # %d", id )); state->error = 1; return NULL; } } if( right_operand_id != -1 ) { right_operand = getExpression( state, right_operand_id ); if( !right_operand ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to get right operand in expression # %d", id )); state->error = 1; expressionFree( left_operand ); return NULL; } } } else if( EXP_IN == type ) { if( -1 == left_operand_id ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "IN condition has no left operand in expression # %d", id )); state->error = 1; return NULL; } else { left_operand = getExpression( state, left_operand_id ); if( !left_operand ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to get left operand for IN condition in expression # %d", id )); state->error = 1; return NULL; } } if( -1 == subquery_id ) { // To do: load IN list of subexpressions osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "IN lists not yet supported for expression # %d", id )); state->error = 1; return NULL; } else { subquery = getStoredQuery( state, subquery_id ); if( !subquery ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to load subquery for IN expression # %d", id )); state->error = 1; return NULL; } } } else if( EXP_EXIST == type ) { if( -1 == subquery_id ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Internal error: No subquery found for EXIST expression # %d", id )); state->error = 1; return NULL; } else { subquery = getStoredQuery( state, subquery_id ); if( !subquery ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to load subquery for EXIST expression # %d", id )); state->error = 1; return NULL; } } } else if( EXP_SUBQUERY == type ) { if( -1 == subquery_id ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Subquery expression # %d has no query id", id )); state->error = 1; return NULL; } else { // Load a subquery, if there is one subquery = getStoredQuery( state, subquery_id ); if( !subquery ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to load subquery for expression # %d", id )); state->error = 1; return NULL; } if( subquery->select_list && subquery->select_list->next ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Subquery # %d as expression returns more than one column", subquery_id )); state->error = 1; return NULL; } PRINT( "\tExpression is subquery %d\n", subquery_id ); } } // Allocate an Expression: from the free list if possible, from the heap if necessary Expression* exp = NULL; if( free_expression_list ) { exp = free_expression_list; free_expression_list = free_expression_list->next; } else exp = safe_malloc( sizeof( Expression ) ); // Populate the Expression exp->next = NULL; exp->id = id; exp->type = type; exp->parenthesize = parenthesize; exp->parent_expr_id = parent_expr_id; exp->seq_no = seq_no; exp->literal = literal ? strdup( literal ) : NULL; exp->table_alias = table_alias ? strdup( table_alias ) : NULL; exp->column_name = column_name ? strdup( column_name ) : NULL; exp->left_operand = left_operand; exp->op = operator ? strdup( operator ) : NULL; exp->right_operand = right_operand; exp->function_id = function_id; exp->subquery_id = subquery_id; exp->subquery = subquery; exp->cast_type_id = subquery_id; return exp; }
static FromRelation* constructFromRelation( BuildSQLState* state, dbi_result result ) { // Get the column values from the result int id = dbi_result_get_int_idx( result, 1 ); const char* type_str = dbi_result_get_string_idx( result, 2 ); FromRelationType type; if( !strcmp( type_str, "RELATION" )) type = FRT_RELATION; else if( !strcmp( type_str, "SUBQUERY" )) type = FRT_SUBQUERY; else if( !strcmp( type_str, "FUNCTION" )) type = FRT_FUNCTION; else type = FRT_RELATION; // shouldn't happen due to database constraint const char* table_name = dbi_result_get_string_idx( result, 3 ); const char* class_name = dbi_result_get_string_idx( result, 4 ); int subquery_id; if( dbi_result_field_is_null_idx( result, 5 ) ) subquery_id = -1; else subquery_id = dbi_result_get_int_idx( result, 5 ); int function_call_id; if( dbi_result_field_is_null_idx( result, 6 ) ) function_call_id = -1; else function_call_id = dbi_result_get_int_idx( result, 6 ); const char* table_alias = dbi_result_get_string_idx( result, 7 ); int parent_relation_id; if( dbi_result_field_is_null_idx( result, 8 ) ) parent_relation_id = -1; else parent_relation_id = dbi_result_get_int_idx( result, 8 ); int seq_no = dbi_result_get_int_idx( result, 9 ); JoinType join_type; const char* join_type_str = dbi_result_get_string_idx( result, 10 ); if( !join_type_str ) join_type = JT_NONE; else if( !strcmp( join_type_str, "INNER" ) ) join_type = JT_INNER; else if( !strcmp( join_type_str, "LEFT" ) ) join_type = JT_LEFT; else if( !strcmp( join_type_str, "RIGHT" ) ) join_type = JT_RIGHT; else if( !strcmp( join_type_str, "FULL" ) ) join_type = JT_FULL; else join_type = JT_NONE; // shouldn't happen due to database constraint int on_clause_id; if( dbi_result_field_is_null_idx( result, 11 ) ) on_clause_id = -1; else on_clause_id = dbi_result_get_int_idx( result, 11 ); StoredQ* subquery = NULL; switch ( type ) { case FRT_RELATION : break; case FRT_SUBQUERY : if( -1 == subquery_id ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Internal error: no subquery specified for FROM relation # %d", id )); state->error = 1; return NULL; } if( ! table_alias ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Subquery needs alias in FROM relation # %d", id )); state->error = 1; return NULL; } subquery = getStoredQuery( state, subquery_id ); if( ! subquery ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to load subquery for FROM relation # %d", id )); state->error = 1; return NULL; } break; case FRT_FUNCTION : osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Functions in FROM clause not yet supported" )); state->error = 1; return NULL; } FromRelation* join_list = getJoinList( state, id ); if( state->error ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to load join list for FROM relation # %d", id )); return NULL; } Expression* on_clause = NULL; if( on_clause_id != -1 ) { on_clause = getExpression( state, on_clause_id ); if( !on_clause ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to load ON condition for FROM relation # %d", id )); joinListFree( join_list ); return NULL; } else PRINT( "\tGot an ON condition\n" ); } // Allocate a FromRelation: from the free list if possible, from the heap if necessary FromRelation* fr; if( free_from_relation_list ) { fr = free_from_relation_list; free_from_relation_list = free_from_relation_list->next; } else fr = safe_malloc( sizeof( FromRelation ) ); // Populate the FromRelation fr->next = NULL; fr->id = id; fr->type = type; fr->table_name = table_name ? strdup( table_name ) : NULL; fr->class_name = class_name ? strdup( class_name ) : NULL; fr->subquery_id = subquery_id; fr->subquery = subquery; fr->function_call_id = function_call_id; fr->table_alias = table_alias ? strdup( table_alias ) : NULL; fr->parent_relation_id = parent_relation_id; fr->seq_no = seq_no; fr->join_type = join_type; fr->on_clause = on_clause; fr->join_list = join_list; return fr; }
static StoredQ* constructStoredQ( BuildSQLState* state, dbi_result result ) { // Get the column values from the result int id = dbi_result_get_int_idx( result, 1 ); const char* type_str = dbi_result_get_string_idx( result, 2 ); QueryType type; if( !strcmp( type_str, "SELECT" )) type = QT_SELECT; else if( !strcmp( type_str, "UNION" )) type = QT_UNION; else if( !strcmp( type_str, "INTERSECT" )) type = QT_INTERSECT; else if( !strcmp( type_str, "EXCEPT" )) type = QT_EXCEPT; else { osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Invalid query type \"%s\"", type_str )); return NULL; } int use_all = oils_result_get_bool_idx( result, 3 ); int use_distinct = oils_result_get_bool_idx( result, 4 ); int from_clause_id; if( dbi_result_field_is_null_idx( result, 5 ) ) from_clause_id = -1; else from_clause_id = dbi_result_get_int_idx( result, 5 ); int where_clause_id; if( dbi_result_field_is_null_idx( result, 6 ) ) where_clause_id = -1; else where_clause_id = dbi_result_get_int_idx( result, 6 ); int having_clause_id; if( dbi_result_field_is_null_idx( result, 7 ) ) having_clause_id = -1; else having_clause_id = dbi_result_get_int_idx( result, 7 ); FromRelation* from_clause = NULL; if( QT_SELECT == type ) { // A SELECT query needs a FROM clause; go get it if( from_clause_id != -1 ) { from_clause = getFromRelation( state, from_clause_id ); if( !from_clause ) { osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to construct FROM clause for id = %d", from_clause_id )); return NULL; } } } else { // Must be one of UNION, INTERSECT, or EXCEPT if( from_clause_id != -1 ) osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "FROM clause found and ignored for %s query in query #%d", type_str, id )); } // If this is a SELECT query, we need a SELECT list. Go get one. SelectItem* select_list = NULL; QSeq* child_list = NULL; if( QT_SELECT == type ) { select_list = getSelectList( state, id ); if( !select_list ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "No SELECT list found for query id = %d", id )); fromRelationFree( from_clause ); return NULL; } } else { // Construct child queries of UNION, INTERSECT, or EXCEPT query child_list = loadChildQueries( state, id, type_str ); if( !child_list ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to load child queries for %s query # %d", type_str, id )); state->error = 1; fromRelationFree( from_clause ); return NULL; } } // Get the WHERE clause, if there is one Expression* where_clause = NULL; if( where_clause_id != -1 ) { where_clause = getExpression( state, where_clause_id ); if( ! where_clause ) { // shouldn't happen due to foreign key constraint osrfLogError( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to fetch WHERE expression for query id = %d", id )); freeQSeqList( child_list ); fromRelationFree( from_clause ); selectListFree( select_list ); return NULL; } } // Get the ORDER BY clause, if there is one OrderItem* order_by_list = getOrderByList( state, id ); if( state->error ) { osrfLogWarning( OSRF_LOG_MARK, sqlAddMsg( state, "Unable to load ORDER BY clause for query %d", id )); expressionFree( where_clause ); freeQSeqList( child_list ); fromRelationFree( from_clause ); selectListFree( select_list ); return NULL; } // Allocate a StoredQ: from the free list if possible, from the heap if necessary StoredQ* sq; if( free_storedq_list ) { sq = free_storedq_list; free_storedq_list = free_storedq_list->next; } else sq = safe_malloc( sizeof( StoredQ ) ); // Populate the StoredQ sq->next = NULL; sq->id = id; sq->type = type; sq->use_all = use_all; sq->use_distinct = use_distinct; sq->from_clause = from_clause; sq->where_clause = where_clause; sq->select_list = select_list; sq->child_list = child_list; sq->order_by_list = order_by_list; return sq; }
//******************************************************************* // retrieve the definitions + status // get it from the cache. if there but too old: delete // If a probe definition does not exist, it will be created. // in case of mysql-has-gone-away type errors, we keep on running, // it will be caught later-on. //******************************************************************* void *bb_get_def(trx *t, int create) { struct probe_def *def; struct bb_result *res = (struct bb_result *)t->res; dbi_result result; def = g_malloc0(t->probe->def_size); def->stamp = time(NULL); def->server = res->server; def->pgroup = 1; strcpy(def->hide, "no"); if (res->color == STAT_PURPLE && res->probeid) { // find the definition based on the probe id result = db_query(t->probe->db, 0, "select id, contact, hide, email, sms, delay from pr_bb_def " "where id = '%u'", res->probeid); if (!result) { g_free(def); return(NULL); } } else { if (res->server == 0) { // first we find the serverid, this will be used to find the probe definition in the database if (!query_server_by_name) { LOG(LOG_WARNING, "%s:%u@%s: don't know how to find %s by name", res->realm, res->stattime, t->fromhost, res->hostname); g_free(def); return(NULL); } result = db_query(t->probe->db, 0, query_server_by_name, res->hostname, res->hostname, res->hostname, res->hostname, res->hostname); if (!result) { g_free(def); return(NULL); } if (dbi_result_next_row(result)) { res->server = dbi_result_get_int_idx(result, 0); } else { LOG(LOG_WARNING, "%s:%u@%s: server %s not found", res->realm, res->stattime, t->fromhost, res->hostname); dbi_result_free(result); g_free(def); return(NULL); } dbi_result_free(result); } // first find the definition based on the serverid result = db_query(t->probe->db, 0, "select id, contact, hide, email, sms, delay from pr_bb_def " "where bbname = '%s' and server = '%u'", res->bbname, res->server); if (!result) { g_free(def); return(NULL); } } if (dbi_result_get_numrows(result) == 0) { // DEF RECORD NOT FOUND char sequence[40]; dbi_result_free(result); result = db_query(t->probe->db, 0, "insert into pr_%s_def (server, ipaddress, description, bbname) " " values ('%u', '%s', '%s', '%s')", res->name, res->server, res->ipaddress ? res->ipaddress : "", res->hostname, res->bbname); dbi_result_free(result); sprintf(sequence, "pr_%s_def_id_seq", res->name); def->probeid = dbi_conn_sequence_last(t->probe->db, sequence); LOG(LOG_NOTICE, "%s:%u@%s: pr_bb_def %s created for %s, id = %u", res->realm, res->stattime, t->fromhost, res->bbname, res->hostname, def->probeid); result = db_query(t->probe->db, 0, "select id, contact, hide, email, sms, delay from pr_bb_def " "where bbname = '%s' and server = '%u'", res->bbname, res->server); if (!result) return(NULL); } if (!dbi_result_next_row(result)) { LOG(LOG_NOTICE, "%s:%u@%s: no pr_%s_def found for server %u - skipped", res->realm, res->stattime, t->fromhost, res->name, res->server); dbi_result_free(result); return(NULL); } def->probeid = dbi_result_get_int(result, "id"); def->contact = dbi_result_get_int(result, "contact"); strcpy(def->hide, dbi_result_get_string_default(result, "hide", "no")); strcpy(def->email, dbi_result_get_string_default(result, "email", "")); strcpy(def->sms, dbi_result_get_string_default(result, "sms", "")); def->delay = dbi_result_get_int(result, "delay"); dbi_result_free(result); // definition found, get the pr_status result = db_query(t->probe->db, 0, "select color, stattime " "from pr_status " "where class = '%u' and probe = '%u'", t->probe->class, def->probeid); if (result) { if (dbi_result_next_row(result)) { def->color = dbi_result_get_int(result, "color"); def->newest = dbi_result_get_int(result, "stattime"); } else { LOG(LOG_NOTICE, "%s:%u@%s: pr_status record for %s id %u (server %s) not found", res->realm, res->stattime, t->fromhost, res->name, def->probeid, res->hostname); } dbi_result_free(result); } if (!def->color) def->color = res->color; res->probeid = def->probeid; return(def); }