Cross reference for modules/qi/query_instructions.c of index.

# File modules/qi/query_instructions.c

      $Revision: 1.75 $

      Query instructions (qi).  This is where the queries are executed.

      Status: NOT REVUED, TESTED

## Included Files

- `#include <stdio.h>`

- `#include <string.h>`

- `#include <glib.h>`

- `#include "include/which_keytypes.h"`
  - `#include "include/bitmask.h"`

- `#include "modules/qi/query_instructions.h"`
  - `#include "include/rxroutines.h"`
    - `#include <glib.h>`
    - `#include <pthread.h>`
    - `#include <include/stubs.h>`
    - `#include <include/memwrap.h>`
    - `#include <stdio.h>`
    - `#include <include/iproutines.h>`
    - `#include <erroutines.h>`
    - `#include "include/sk.h"`
      - `#include "include/stubs.h"`
      - `#include <sys/types.h>`
      - `#include <sys/socket.h>`
      - `#include <netinet/in.h>`
      - `#include <netdb.h>`
      - `#include <pthread.h>`
      - `#include <stdlib.h>`
      - `#include <errno.h>`
      - `#include <fcntl.h>`
      - `#include <signal.h>`
      - `#include <stdio.h>`
      - `#include "include/iproutines.h"`
    - `#include "include/thread.h"`
  - `#include "include/iproutines.h"`
  - `#include "include/mysql_driver.h"`
    - `#include "/opt/package/mysql/include/mysql/mysql.h"`
      - `#include <sys/types.h>`
      - `#include "/opt/package/mysql/include/mysql/mysql_com.h"`
      - `#include "/opt/package/mysql/include/mysql/mysql_version.h"`
    - `#include "/opt/package/mysql/include/mysql/mysqld_error.h"`
    - `#include "include/erroutines.h"`
  - `#include "include/query_command.h"`
    - `#include <glib.h>`
    - `#include "include/bitmask.h"`
    - `#include "include/sk.h"`
  - `#include "include/defs.h"`
    - `#include <glib.h>`
    - `#include "include/bitmask.h"`
    - `#include "include/DF_class_enum.def"`
    - `#include "include/DF_class_mask.def"`
    - `#include "include/DF_attribute_enum.def"`
    - `#include "include/DF_attribute_inv_attr_mask.def"`
    - `#include "include/which_keytypes.h"`
    - `#include "include/iproutines.h"`
    - `#include "include/rxroutines.h"`
  - `#include "include/which_keytypes.h"`
  - `#include "include/access_control.h"`
    - `#include "include/erroutines.h"`
    - `#include "include/iproutines.h"`
    - `#include "include/rxroutines.h"`
    - `#include "include/mysql_driver.h"`
  - `#include "include/ca_configFns.h"`
    - `#include "include/ca_defs.h"`
      - `#include <pthread.h>`
      - `#include <glib.h>`
  - `#include "include/ca_dictionary.h"`
  - `#include "include/ca_macros.h"`
    - `#include "include/ca_adminAttribs.h"`
  - `#include "include/ca_srcAttribs.h"`

- `#include "include/mysql_driver.h"`

- `#include "include/rp.h"`
  - `#include <stddef.h>`
  - `#include <glib.h>`
  - `#include <defs.h>`
  - `#include <iproutines.h>`
  - `#include <erroutines.h>`
  - `#include <rxroutines.h>`
  - `#include <mysql_driver.h>`
  - `#include "include/ca_defs.h"`

- `#include "include/stubs.h"`

- `#include "include/constants.h"`
  - `#include <glib.h>`

- `#include "include/memwrap.h"`

- `#include "include/wh_queries.h"`
  - `#include "include/sk.h"`

- `#include "include/defs.h"`

## Preprocessor definitions

String sizes

`#define STR_S 63`

`#define STR_M 255`

`#define STR_L 1023`

`#define STR_XL 4095`

`#define STR_XXL 16383`

## Global Variable Lock

`pthread_mutex_t Lock`

Included from | include/ca_defs.h
Visible in: |  | modules/ac/access_control.c
|  | modules/ca/ca_configFns.c
|  | modules/ca/ca_initFn.c
|  | modules/ca/ca_sanityCheck.c
|  | modules/ca/ca_sourceLoader.c
|  | modules/ca/ca_values.c
|  | modules/er/er_macro.c
|  | modules/pm/pm_serials.c
|  | modules/pm/protocol_mirror.c
|  | modules/pw/protocol_whois.c
|  | modules/qc/query_command.c
|  | modules/qi/query_instructions.c
Used in: | ca_get_adminIntElement() | modules/ca/ca_configFns.c
| ca_get_adminStrElement() | modules/ca/ca_configFns.c
| ca_get_boolean() | modules/ca/ca_configFns.c
| ca_get_dirlist() | modules/ca/ca_configFns.c
| ca_get_int() | modules/ca/ca_configFns.c
| ca_get_string() | modules/ca/ca_configFns.c
| ca_set_boolean() | modules/ca/ca_configFns.c
| ca_set_string() | modules/ca/ca_configFns.c
| ca_srchandle2Intelement() | modules/ca/ca_configFns.c
| ca_srchandle2Strelement() | modules/ca/ca_configFns.c

## Global Variable newPort

`char newPort[16]`

Included from | include/ca_defs.h
Visible in: |  | modules/ac/access_control.c
|  | modules/ca/ca_configFns.c
|  | modules/ca/ca_initFn.c
|  | modules/ca/ca_sanityCheck.c
|  | modules/ca/ca_sourceLoader.c
|  | modules/ca/ca_values.c
|  | modules/er/er_macro.c
|  | modules/pm/pm_serials.c
|  | modules/pm/protocol_mirror.c
|  | modules/pw/protocol_whois.c
|  | modules/qc/query_command.c
|  | modules/qi/query_instructions.c

## Global Function QI_execute()

      Execute the query instructions.  This is called for each source.
      This is linked into MySQL by the fact that MySQL doesn't have sub selects
     (yet).  The queries are done in two stages.  Make some temporary tables and
      insert into them.  Then use them in the next select.

      More:

      Authors:
            ottrey - original version,
    	marek - the rest.

`er_ret_t QI_execute ( ca_dbSource_t* dbhdl, Query_instructions* qis, Query_environ* qe, acc_st* acc_credit, acl_st* acl )`

`ca_dbSource_t* dbhdl`
  source-specific identifier (defined in CA)
`Query_instructions* qis`
  query instructions.
`Query_environ* qe`
  query environment.
`acc_st* acc_credit`
  object display credit
`acl_st* acl`
  copy of the original acl for this client

Prototyped in: | modules/qi/query_instructions.h
Calls: | ER_perror() | modules/er/er.c
| ca_srchandle2Intelement() | modules/ca/ca_configFns.c
| ca_srchandle2Strelement() | modules/ca/ca_configFns.c
| insert_radix_serials() | modules/qi/query_instructions.c
| qi_collect_ids() | modules/qi/query_instructions.c
| qi_fetch_references() | modules/qi/query_instructions.c
| write_objects() | modules/qi/query_instructions.c
| write_radix_immediate() | modules/qi/query_instructions.c
| SK_watch_setclear(), SK_watchstart(), SK_watchstop(), SQ_close_connection(), SQ_errno(), SQ_error(), SQ_execute_query(), SQ_get_connection(), fprintf(), pthread_self(), sprintf(), wr_real_free()
Called by: | PW_process_qc() | modules/pw/protocol_whois.c

## Global Function QI_fast_output()

      This is for the '-F' flag.
      It assumes lines starting with ' ', '\t' or '+' belong to the prior attribute.
      Fast isn't fast anymore - it's just there for compatibility reasons.

      More:

      Authors:
            ottrey,
    	marek - glib strings + small changes

`char* QI_fast_output ( const char* str )`

`const char* str`
  The object to be "fast output'ed".

Prototyped in: | modules/qi/query_instructions.h
Calls: | DF_attribute_name2type() | modules/df/defs.c
| DF_get_attribute_code() | modules/df/defs.c
| ER_perror() | modules/er/er.c
| fprintf(), g_strfreev(), g_string_append(), g_string_append_c(), g_string_assign(), g_string_free(), g_string_sized_new(), g_strsplit(), strchr(), strdup()
Called by: | write_results() | modules/qi/query_instructions.c

## Global Function QI_free()

      Free the query_instructions.

      More:

      Authors:
            ottrey, marek

`void QI_free ( Query_instructions* qis )`

`Query_instructions* qis`
  Query_instructions to be freed.

Prototyped in: | modules/qi/query_instructions.h
Calls: | instruction_free() | modules/qi/query_instructions.c
| wr_real_free()
Called by: | PW_process_qc() | modules/pw/protocol_whois.c

## Global Function QI_new()

      Create a new set of query_instructions. Returns an allocated structure which
      must be freed after use with QI_free().

      Authors:
            ottrey,
    	marek.

`Query_instructions* QI_new ( const Query_command* qc, const Query_environ* qe )`

`const Query_command* qc`
  The query_command that the instructions are created from.
`const Query_environ* qe`
  The environmental variables that they query is being performed under.

Prototyped in: | modules/qi/query_instructions.h
Calls: | ER_dbg_va() | modules/er/er.c
| QI_queries_to_string() | modules/qi/query_instructions.c
| create_query() | modules/qi/query_instructions.c
| map_qc2rx() | modules/qi/query_instructions.c
| valid_query() | modules/qi/query_instructions.c
| fprintf(), wr_real_calloc(), wr_real_free()
Called by: | PW_process_qc() | modules/pw/protocol_whois.c
References Variables: | Query | modules/df/defs.c

## Global Function QI_queries_to_string()

      Author:
         marek.

`char* QI_queries_to_string ( Query_instructions* qis )`

`char* QI_queries_to_string`
  returns a list of descriptions for queries that will be performed (debugging only). Allocated text, must be freed after use.
`Query_instructions* qis`
  query instructions structure

Prototyped in: | modules/qi/query_instructions.h
Calls: | fprintf(), strcat(), strcpy(), strlen(), wr_real_realloc()
Called by: | QI_new() | modules/qi/query_instructions.c
References Variables: | Query | modules/df/defs.c

## Global Function filter()

      Basically it's for the '-K' flag for non-set (and non-radix) objects.
      It assumes lines starting with ' ', '\t' or '+' belong to the prior attribute.

      This could be speed up if there were breaks out of the loops, once it matched something.

      More:

      Authors:
            ottrey

`char* filter ( const char* str )`

`const char* str`
  ng The string to be filtered.

Calls: | DF_get_filter_names() | modules/df/defs.c
| g_strfreev(), g_string_append(), g_string_assign(), g_string_free(), g_string_sized_new(), g_string_sprintfa(), g_strsplit(), strdup(), strlen(), strncmp()
Called by: | write_results() | modules/qi/query_instructions.c

## Global Function run_referral()

       invoked when no such domain found. Goes through the domain table
       and searches for shorter domains, then if it finds one with referral
       it performs it, otherwise it just returns nothing.

       to perform referral, it actually composes the referral query
       for a given host/port/type and calls the whois query function.

       Well, it returns nothing anyway (void). It just prints to the socket.

      Author:
        marek

`void run_referral ( Query_environ* qe, char* ref_host, unsigned ref_port_int, char* ref_type, char* qry )`

`Query_environ* qe`
  &nbs;
`char* ref_host`
  referral server host name
`unsigned ref_port_int`
  referral server port number
`char* ref_type`
  referral type name
`char* qry`
  query to be run

Calls: | ca_get_int() | modules/ca/ca_configFns.c
| ca_get_string() | modules/ca/ca_configFns.c
| SK_cd_puts(), WH_cd_sock(), fprintf(), wr_real_free()
Called by: | qi_prep_run_refer() | modules/qi/query_instructions.c

## Global Function sql_execute_watched()

      wrapper around sq_execute_query: starts a query
      in a separate thread and starts the socket watchdog to cancel the query
      if the socket is closed. If the socket has problems already (its
      reason-to-close flag is set) no query is attempted.

      The execution of the query or watchdog is not guaranteed at all!

      SQ_connection_t **sql_connection  sql connection

      SQ_result_set_t **result_ptr      storage for the query result structure
                                        (passed to SQ_execute_query). Must either
    				    be NULL, or the pointer it points to must
    				    be NULL - in that case the result struct.
    				    will be allocated in SQ.

      Author:
        marek.

`int sql_execute_watched ( sk_conn_st* condat, MYSQL** sql_connection, const char* query, MYSQL_RES** result_ptr )`

`int sql_execute_watched`
  Returns the return code of SQ_execute_query, Returns 0 for cancelled queries.
`sk_conn_st* condat`
  connection to watch
`MYSQL** sql_connection`
  &nbs;
`const char* query`
  sql query to execute
`MYSQL_RES** result_ptr`
  &nbs;

Calls: | ER_dbg_va() | modules/er/er.c
| SK_watch_setclear(), SK_watch_setexec(), SK_watchstart(), SK_watchstop(), SQ_close_connection(), SQ_duplicate_connection(), SQ_execute_query(), SQ_free_result(), fprintf()
Called by: | qi_collect_ids() | modules/qi/query_instructions.c
| qi_fetch_references() | modules/qi/query_instructions.c
| write_objects() | modules/qi/query_instructions.c
References Functions: | qi_kill_body() | modules/qi/query_instructions.c

## Local Function add_filter()

      add_filter(): construct a query to limit the objects returned from the last
      table to predefined types.

      Author:
        ottrey.

`static void add_filter ( char* query_str, const Query_command* qc )`

`char* query_str`
  buffer for the final query, containing the initial part of the query (must be big enough)
`const Query_command* qc`
  query command structure with the bitmap of object types to be included.

Calls: | MA_bitcount() | modules/ma/bitmask.c
| MA_isset() | modules/ma/bitmask.c
| sprintf(), strcat(), strcpy(), strlen()
Called by: | create_query() | modules/qi/query_instructions.c

## Local Function add_ref_name()

      Creates a SQL query for a reference-by-name lookup. Uses standard name
      lookup query generator (create_name_query), so the order of the names
      doesn't matter.

      SQ_connection_t *sql_connection   sql connection dedicated to this thread

`static void add_ref_name ( MYSQL* sql_connection, char* rectable, char* allnames )`

`MYSQL* sql_connection`
  &nbs;
`char* rectable`
  table in which to look up
`char* allnames`
  all name words to be looked up, space delimited.

Calls: | create_name_query() | modules/qi/query_instructions.c
| SQ_execute_query(), fprintf(), sprintf(), strlen()
Called by: | qi_fetch_references() | modules/qi/query_instructions.c

## Local Function create_asblock_query()

      construct a range query for the as_block table
      (a query for an AS block object) given a string like:
      AS1
      AS1 - AS10
      AS1-AS10

      Author:
        marek

`static int create_asblock_query ( char* query_str, const char* sql_query, const char* keys )`

`int create_asblock_query`
  Returns 0 on success, -1 on failure (search term not an AS# nor range)
`char* query_str`
  buffer for the final query (must be big enough)
`const char* sql_query`
  rest of the sql query (with %d %d formats for AS numbers)
`const char* keys`
  user-supplied search term.

Calls: | sprintf(), sscanf(), strtok_r(), wr_real_free(), wr_real_string()
Called by: | create_query() | modules/qi/query_instructions.c

## Local Function create_name_query()

      Create an sql query for the names table.

      More:

      Authors:
        ottrey

`static void create_name_query ( char* query_str, const char* sql_query, const char* keys )`

Calls: | g_strfreev(), g_string_free(), g_string_sized_new(), g_string_sprintfa(), g_strsplit(), sprintf()
Called by: | add_ref_name() | modules/qi/query_instructions.c
| create_query() | modules/qi/query_instructions.c

## Local Function create_query()

      Create an sql query from the query_command and the matching keytype and the
      selected inverse attributes.
      Note this clears the first inv_attribute it sees, so is called sequentially
      until there are no inv_attributes left.

      WK_Type keytype The matching keytype.

      mask_t *inv_attrs_bitmap The selected inverse attributes.

      More:

      Authors:
            ottrey

`static char* create_query ( const Query_t q, const Query_command* qc )`

`const Query_t q`
  &nbs;
`const Query_command* qc`
  The query command.

Calls: | IP_rang_b2_space() | modules/ip/ip.c
| IP_rang_b2v4() | modules/ip/ip.c
| IP_smart_range() | modules/ip/ip.c
| MA_bitcount() | modules/ma/bitmask.c
| NOERR() | modules/er/er.c
| add_filter() | modules/qi/query_instructions.c
| create_asblock_query() | modules/qi/query_instructions.c
| create_name_query() | modules/qi/query_instructions.c
| fprintf(), sprintf(), strcpy(), strlen(), wr_real_malloc()
Called by: | QI_new() | modules/qi/query_instructions.c

## Local Function insert_radix_serials()

      Insert the radix serial numbers into a temporary table in the database.

      mask_t bitmap The bitmap of attribute to be converted.

      SQ_connection_t *sql_connection The connection to the database.

      More:

      Authors:
            ottrey,
    	marek

`static void insert_radix_serials ( sk_conn_st* condat, MYSQL* sql_connection, char* id_table, GList* datlist )`

`sk_conn_st* condat`
  &nbs;
`MYSQL* sql_connection`
  &nbs;
`char* id_table`
  The id of the temporary table (This is a result of the hacky way we've tried to get MySQL to do sub-selects.)
`GList* datlist`
  The list of data from the radix tree.

Calls: | SQ_execute_query(), fprintf(), g_list_first(), sprintf(), wr_real_clear_list(), wr_real_free()
Called by: | QI_execute() | modules/qi/query_instructions.c

## Local Function instruction_free()

      Free the instruction.

      More:

      Authors:
            ottrey

`static void instruction_free ( Query_instruction* qi )`

`Query_instruction* qi`
  query_instruction to be freed.

Calls: | wr_real_free()
Called by: | QI_free() | modules/qi/query_instructions.c

## Local Function map_qc2rx()

      The mapping between a query_command and a radix query.

      More:

      Authors:
            ottrey,
    	marek - simplified the logic, added stealth -S option

`static int map_qc2rx ( Query_instruction* qi, const Query_command* qc )`

`Query_instruction* qi`
  The Query Instruction to be created from the mapping of the query command.
`const Query_command* qc`
  The query command to be mapped.

Calls: | ER_dbg_va() | modules/er/er.c
Called by: | QI_new() | modules/qi/query_instructions.c

## Local Function qi_collect_domain()

      specific case of the object ID collection: the domains.
      Checks to see if the domain exists, and runs the referral if it is defined
      and the domain is missing.

      Arguments:

      SQ_connection_t *sql_connection      sql connection dedicated to this thread

      Author:
         marek.

`static int qi_collect_domain ( char* sourcename, MYSQL* sql_connection, char* id_table, char* sub_table, Query_instructions* qis, Query_environ* qe, Query_instruction* qi, acc_st* acc_credit )`

`char* sourcename`
  name of the database "source"
`MYSQL* sql_connection`
  &nbs;
`char* id_table`
  name of the temporary table to be used
`char* sub_table`
  name of the temporary subtable
`Query_instructions* qis`
  original query instructions structure
`Query_environ* qe`
  original query environment structure
`Query_instruction* qi`
  specific query instruction triggered
`acc_st* acc_credit`
  credit for this client

Calls: | ER_dbg_va() | modules/er/er.c
| qi_prep_run_refer() | modules/qi/query_instructions.c
| SQ_execute_query(), SQ_free_result(), SQ_get_affected_rows(), SQ_num_rows(), SQ_row_next(), fprintf(), index(), sprintf()
Called by: | qi_collect_ids() | modules/qi/query_instructions.c
References Variables: | Query | modules/df/defs.c

## Local Function qi_collect_ids()

      collects object ID's from all queries defined in the Query_instructions
      array. The results from RADIX trees are maintained in a linked list, the
      results from SQL lookups are kept in a temporary table. For domains,
      a specific function is invoked that may run the referral.
      Any sql lookup will be limited to the maximum number of objects allowed
      for the client (acl and credit are checked for this).
      The routine uses its own temporary _S table, destroyed at exit.

      SQ_connection_t **sql_connection  sql connection dedicated to this thread
                                        (replaced on cancel)

`static void qi_collect_ids ( ca_dbSource_t* dbhdl, char* sourcename, MYSQL** sql_connection, Query_instructions* qis, Query_environ* qe, char* id_table, GList** datlist, acc_st* acc_credit, acl_st* acl )`

`ca_dbSource_t* dbhdl`
  source-specific identifier (defined in CA)
`char* sourcename`
  name of the database "source"
`MYSQL** sql_connection`
  &nbs;
`Query_instructions* qis`
  original query instructions structure
`Query_environ* qe`
  original query environment structure
`char* id_table`
  the table to store the ID's found
`GList** datlist`
  the list to store the Radix leaves found
`acc_st* acc_credit`
  credit for this client
`acl_st* acl`
  acl for this client

Calls: | AC_get_higher_limit() | modules/ac/access_control.c
| ER_dbg_va() | modules/er/er.c
| ER_inf_va() | modules/er/er.c
| ER_is_traced() | modules/er/er.c
| ER_perror() | modules/er/er.c
| NOERR() | modules/er/er.c
| qi_collect_domain() | modules/qi/query_instructions.c
| sql_execute_watched() | modules/qi/query_instructions.c
| RP_asc_search(), SQ_errno(), SQ_error(), SQ_execute_query(), SQ_get_affected_rows(), fprintf(), g_list_length(), sprintf(), strcpy()
Called by: | QI_execute() | modules/qi/query_instructions.c
References Variables: | Query | modules/df/defs.c

## Local Function qi_fetch_references()

      given the list of object ID's collects the references from these objects
      to person and role objects. Uses its own temporary SQL table (_R)
      and upon completion transfers the results from it to the main
      temporary table. Runs queries in watched mode, to be able to cancel them.

      SQ_connection_t **sql_connection  sql connection dedicated to this thread
                                        (replaced on cancel)

`static void qi_fetch_references ( MYSQL** sql_connection, Query_environ* qe, char* id_table, acc_st* acc_credit, acl_st* acl )`

`MYSQL** sql_connection`
  &nbs;
`Query_environ* qe`
  original query environment structure
`char* id_table`
  the table with the ID's found
`acc_st* acc_credit`
  credit for this client
`acl_st* acl`
  acl for this client

Calls: | add_ref_name() | modules/qi/query_instructions.c
| sql_execute_watched() | modules/qi/query_instructions.c
| SQ_execute_query(), SQ_free_result(), SQ_get_column_string(), SQ_row_next(), atoi(), fprintf(), sprintf(), strcat(), wr_real_free()
Called by: | QI_execute() | modules/qi/query_instructions.c

## Local Function qi_kill_body()

      Function invoked on query cancellation by the watchdog,
      used from the sql_execute_watched() function.

      It aborts the running query (the abort function in sq kills and
      reestablished the connection).

      Author:
        marek.

`static void* qi_kill_body ( void* arg )`

`void* qi_kill_body`
  result of sq_execute_query, int cast to (void*)
`void* arg`
  pointer to sql connection

Calls: | ER_dbg_va() | modules/er/er.c
| SQ_abort_query()
Used in: | sql_execute_watched() | modules/qi/query_instructions.c

## Local Function qi_prep_run_refer()

       prepare and run the referral, displaying the results directly to the
       client's connection.

       XXX still missing protection against a referral loop
       XXX handling inverse flag not needed, to be removed

      SQ_result_set_t *result    result of the lookup containing referral details

      SQ_row_t *row              first row (should be only 1) of the result

      Author:
         marek

`static void qi_prep_run_refer ( char* domain, Query_instructions* qis, Query_environ* qe, Query_instruction* qi, MYSQL_RES* result, MYSQL_ROW* row, char* sourcename )`

`char* domain`
  domain being looked up
`Query_instructions* qis`
  original query instructions structure
`Query_environ* qe`
  original query environment structure
`Query_instruction* qi`
  specific query instruction triggered
`MYSQL_RES* result`
  &nbs;
`MYSQL_ROW* row`
  &nbs;
`char* sourcename`
  name of the database "source"

Calls: | ER_dbg_va() | modules/er/er.c
| ca_get_string() | modules/ca/ca_configFns.c
| run_referral() | modules/qi/query_instructions.c
| SK_cd_printf(), SK_cd_puts(), SQ_get_column_string(), fprintf(), snprintf(), sscanf(), strcat(), strcmp(), strcpy(), wr_real_free()
Called by: | qi_collect_domain() | modules/qi/query_instructions.c
References Variables: | Query | modules/df/defs.c

## Local Function valid_query()

      Determine if this query should be conducted or not.

      If it was an inverse query - if the attribute appears in the query command's bitmap.
      If it was a lookup query - if the attribute appears in the object type bitmap or
                                 disregard if there is no object_type bitmap (Ie object filter).

      mask_t bitmap The bitmap of attribute to be converted.

`static int valid_query ( const Query_command* qc, const Query_t q )`

`const Query_command* qc`
  The query_command that the instructions are created from.
`const Query_t q`
  The query being considered.

        Authors:
              ottrey,
      	marek.

Calls: | MA_isset() | modules/ma/bitmask.c
| fprintf()
Called by: | QI_new() | modules/qi/query_instructions.c

## Local Function write_objects()

      SQ_connection_t *sql_connection The connection to the database.

      More:

      Authors:
            ottrey,
    	marek.

`static void write_objects ( MYSQL** sql_connection, char* id_table, unsigned int filtered, unsigned int fast, sk_conn_st* condat, acc_st* acc_credit, acl_st* acl )`

`MYSQL** sql_connection`
  &nbs;
`char* id_table`
  The id of the temporary table (This is a result of the hacky way we've tried to get MySQL to do sub-selects.)
`unsigned int filtered`
  &nbs;
`unsigned int fast`
  &nbs;
`sk_conn_st* condat`
  Connection data for the client
`acc_st* acc_credit`
  &nbs;
`acl_st* acl`
  &nbs;

Calls: | sql_execute_watched() | modules/qi/query_instructions.c
| write_results() | modules/qi/query_instructions.c
| SQ_free_result(), fprintf(), sprintf()
Called by: | QI_execute() | modules/qi/query_instructions.c

## Local Function write_radix_immediate()

      Display the immediate data carried with the objects returned by the
      radix tree.

    More:

      Authors:
            marek

      Also free the list of answers.

`static void write_radix_immediate ( GList* datlist, sk_conn_st* condat, acc_st* acc_credit, acl_st* acl )`

`GList* datlist`
  The linked list of dataleaf copies
`sk_conn_st* condat`
  Connection data for the client
`acc_st* acc_credit`
  Accounting struct
`acl_st* acl`
  &nbs;

Calls: | AC_count_object() | modules/ac/access_control.c
| SK_cd_puts(), g_list_first(), wr_real_clear_list(), wr_real_free()
Called by: | QI_execute() | modules/qi/query_instructions.c

## Local Function write_results()

      Write the results to the client socket.

      SQ_result_set_t *result The result set returned from the sql query.
      unsigned filtered       if the objects should go through a filter (-K)
      sk_conn_st *condat      Connection data for the client

      More:

      Authors:
            ottrey - initial design
    	marek - rewritten for accounting and cancellation.

`static int write_results ( MYSQL_RES* result, unsigned filtered, unsigned fast, sk_conn_st* condat, acc_st* acc_credit, acl_st* acl )`

Calls: | AC_count_object() | modules/ac/access_control.c
| AC_credit_isdenied() | modules/ac/access_control.c
| ER_dbg_va() | modules/er/er.c
| QI_fast_output() | modules/qi/query_instructions.c
| filter() | modules/qi/query_instructions.c
| SK_cd_puts(), SQ_get_column_string(), SQ_row_next(), atoi(), fprintf(), wr_real_free()
Called by: | write_objects() | modules/qi/query_instructions.c