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; }
int dbi_result_field_is_null(dbi_result Result, const char *fieldname) { unsigned int fieldidx = 0; dbi_error_flag errflag; if (!RESULT) { _error_handler(/*RESULT->conn*/ NULL, DBI_ERROR_BADPTR); return DBI_FIELD_FLAG_ERROR; } fieldidx = _find_field(RESULT, fieldname, &errflag); if (errflag != DBI_ERROR_NONE) { _error_handler(RESULT->conn, errflag); return DBI_FIELD_FLAG_ERROR; } return dbi_result_field_is_null_idx(Result, fieldidx+1); }
//******************************************************************* // SUMMARIZE A TABLE INTO AN OLDER PERIOD //******************************************************************* static void mysqlstats_summarize(trx *t, char *from, char *into, guint slot, guint slotlow, guint slothigh, gint resummarize) { dbi_result result; struct probe_def *def = (struct probe_def *)t->def; float avg_yellow, avg_red; int avg_selectq; int avg_insertq; int avg_updateq; int avg_deleteq; guint stattime; guint max_color; stattime = slotlow + ((slothigh-slotlow)/2); result = db_query(t->probe->db, 0, "select avg(selectq) as avg_selectq, avg(insertq) as avg_insertq, avg(updateq) as avg_updateq, " " avg(deleteq) as avg_deleteq, max(color) as max_color, avg(yellow) as avg_yellow, avg(red) as avg_red" "from pr_mysqlstats_%s use index(probstat) " "where probe = '%d' and stattime >= %d and stattime < %d", from, def->probeid, slotlow, slothigh); if (!result) return; if (dbi_result_get_numrows(result) == 0) { // no records found LOG(LOG_NOTICE, "nothing to summarize from %s for probe %u %u %u", from, def->probeid, slotlow, slothigh); dbi_result_free(result); return; } if (!dbi_result_next_row(result)) { dbi_result_free(result); return; } if (dbi_result_field_is_null_idx(result, 0)) { LOG(LOG_NOTICE, "nothing to summarize from %s for probe %u %u %u", from, def->probeid, slotlow, slothigh); dbi_result_free(result); return; } avg_selectq = dbi_result_get_int(result, "avg_selectq"); avg_insertq = dbi_result_get_int(result, "avg_insertq"); avg_updateq = dbi_result_get_int(result, "avg_updateq"); avg_deleteq = dbi_result_get_int(result, "avg_deleteq"); max_color = dbi_result_get_int(result, "max_color"); avg_yellow = dbi_result_get_float(result, "avg_yellow"); avg_red = dbi_result_get_float(result, "avg_red"); dbi_result_free(result); if (resummarize) { // delete old values result = db_query(t->probe->db, 0, "delete from pr_mysqlstats_%s where probe = '%u' and stattime = '%u'", into, def->probeid, stattime); dbi_result_free(result); } result = db_query(t->probe->db, 0, "insert into pr_mysqlstats_%s (selectq, insertq, updateq, deleteq, probe, color, stattime, " " yellow, red, slot) " " values ('%u', '%u', '%u', '%u', '%d', '%u', '%d', " " '%f', '%f', '%u')", into, avg_selectq, avg_insertq, avg_updateq, avg_deleteq, def->probeid, max_color, stattime, avg_yellow, avg_red, slot); dbi_result_free(result); }
//******************************************************************* // SUMMARIZE A TABLE INTO AN OLDER PERIOD //******************************************************************* static void bb_cpu_summarize(trx *t, char *from, char *into, guint slot, guint slotlow, guint slothigh, gint resummarize) { dbi_result result; struct probe_def *def = (struct probe_def *)t->def; float avg_yellow, avg_red; gfloat avg_loadavg; guint avg_user, avg_system, avg_idle; guint avg_swapped, avg_free, avg_buffered, avg_cached, avg_used; guint stattime; guint max_color; stattime = slotlow + ((slothigh-slotlow)/2); result = db_query(t->probe->db, 0, "select avg(loadavg) as avg_loadavg, avg(user) as avg_user, avg(system) as avg_system, " " avg(idle) as avg_idle, avg(swapped) as avg_swapped, avg(free) as avg_free, " " avg(buffered) as avg_buffered, avg(cached) as avg_cached, avg(used) as avg_used, " " max(color) as max_color, avg(yellow) as avg_yellow, avg(red) as avg_red " "from pr_bb_cpu_%s use index(probstat) " "where probe = '%d' and stattime >= %d and stattime < %d", from, def->probeid, slotlow, slothigh); if (!result) return; if (dbi_result_get_numrows(result) == 0) { // no records found LOG(LOG_NOTICE, "nothing to summarize from %s for probe %u %u %u", from, def->probeid, slotlow, slothigh); dbi_result_free(result); return; } if (!dbi_result_next_row(result)) { dbi_result_free(result); return; } if (dbi_result_field_is_null_idx(result, 0)) { LOG(LOG_NOTICE, "nothing to summarize from %s for probe %u %u %u", from, def->probeid, slotlow, slothigh); dbi_result_free(result); return; } avg_loadavg = dbi_result_get_float(result, "avg_loadavg"); avg_user = dbi_result_get_int(result, "avg_user"); avg_system = dbi_result_get_int(result, "avg_system"); avg_idle = dbi_result_get_int(result, "avg_idle"); avg_swapped = dbi_result_get_int(result, "avg_swapped"); avg_free = dbi_result_get_int(result, "avg_free"); avg_buffered= dbi_result_get_int(result, "avg_buffered"); avg_cached = dbi_result_get_int(result, "avg_cached"); avg_used = dbi_result_get_int(result, "avg_used"); max_color = dbi_result_get_int(result, "max_color"); avg_yellow = dbi_result_get_float(result, "avg_yellow"); avg_red = dbi_result_get_float(result, "avg_red"); dbi_result_free(result); if (resummarize) { // delete old values result = db_query(t->probe->db, 0, "delete from pr_bb_cpu_%s where probe = '%u' and stattime = '%u'", into, def->probeid, stattime); dbi_result_free(result); } result = db_query(t->probe->db, 0, "insert into pr_bb_cpu_%s (loadavg, user, system, idle, swapped, free, buffered, cached, " " used, probe, color, stattime, yellow, red, slot) " " values ('%f', '%u', '%u', '%u', '%u', '%u', '%u', '%u', " " '%u', '%d', '%u', '%d', '%f', '%f', '%u')", into, avg_loadavg, avg_user, avg_system, avg_idle, avg_swapped, avg_free, avg_buffered, avg_cached, avg_used, def->probeid, max_color, stattime, avg_yellow, avg_red, slot); dbi_result_free(result); }
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; }