/* * parser_free_parser() - clean up all parse structures after they are through * being used. Values which need to be persistent, should have been * copied by now * return: * parser(in): */ void parser_free_parser (PARSER_CONTEXT * parser) { assert (parser != NULL); /* free string blocks */ pt_free_string_blocks (parser); /* free node blocks */ pt_free_node_blocks (parser); pt_unregister_parser (parser); if (parser->error_buffer) free ((char *) parser->error_buffer); if (parser->host_variables) { DB_VALUE *hv; int i; for (i = 0, hv = parser->host_variables; i < parser->host_var_count + parser->auto_param_count; i++, hv++) db_value_clear (hv); free_and_init (parser->host_variables); } parser_free_lcks_classes (parser); free_and_init (parser); }
static void my_crs_printlist (FILE * fp, DB_QUERY_RESULT * result) { DB_VALUE *value_list, *valp; int cnt, k; int pos; cnt = db_query_column_count (result); value_list = (DB_VALUE *) malloc (cnt * sizeof (DB_VALUE)); if (value_list == NULL) { return; } fprintf (fp, "================= Q U E R Y R E S U L T S " "=================\n"); fprintf (fp, "\n"); pos = db_query_first_tuple (result); while (pos == DB_CURSOR_SUCCESS) { if (db_query_get_tuple_valuelist (result, cnt, value_list) != NO_ERROR) { goto cleanup; } fprintf (fp, "\n "); for (k = 0, valp = value_list; k < cnt; k++, valp++) { fprintf (fp, " "); if (DB_VALUE_TYPE (valp) == DB_TYPE_SET || DB_VALUE_TYPE (valp) == DB_TYPE_MULTISET || DB_VALUE_TYPE (valp) == DB_TYPE_SEQUENCE) { my_db_set_print (fp, DB_GET_SET (valp)); } else { db_value_fprint (fp, valp); } fprintf (fp, " "); } /* clear the value list */ for (k = 0, valp = value_list; k < cnt; k++, valp++) { db_value_clear (valp); } pos = db_query_next_tuple (result); } fprintf (fp, "\n"); cleanup: free (value_list); }
/* * parser_free_node () - Return this node to this parser's node memory pool * return: * parser(in): * node(in): * * Note : * This only makes this memory eligible for re-use * by the current parser. To return memory to virtual memory pool, * pt_free_nodes or parser_free_parser should be called. */ void parser_free_node (const PARSER_CONTEXT * parser, PT_NODE * node) { int idhash; PARSER_NODE_FREE_LIST *free_list; #if defined(SERVER_MODE) int rv; #endif /* SERVER_MODE */ /* find free list for for this id */ idhash = parser->id % HASH_NUMBER; #if defined(SERVER_MODE) MUTEX_LOCK (rv, free_lists_lock); #endif /* SERVER_MODE */ free_list = parser_Node_free_lists[idhash]; while (free_list != NULL && free_list->parser_id != parser->id) { free_list = free_list->next; } #if defined(SERVER_MODE) /* we can unlock mutex, since this free_list is only used by one parser */ MUTEX_UNLOCK (free_lists_lock); #endif /* SERVER_MODE */ if (free_list == NULL) { /* this is an programming error ! The parser does not exist! */ return; } if (node->parser_id != parser->id) { /* this is an programming error ! The node is not from this parser. */ return; } /* before we free this node, see if we need to clear a db_value */ if (node->node_type == PT_VALUE && node->info.value.db_value_is_in_workspace) db_value_clear (&node->info.value.db_value); /* * Always set the node type to maximum. This may * keep us from doing bad things to the free list if we try to free * this structure more than once. We shouldn't be doing that (i.e., * we should always be building trees, not graphs) but sometimes it * does by accident, and if we don't watch for it we wind up with * fatal errors. A common symptom is stack exhaustion during parser_free_tree * as we try to recursively walk a cyclic free list. */ node->node_type = PT_NODE_NUMBER; node->next = free_list->node; free_list->node = node; }
/* * cursor_fixup_vobjs () - * return: NO_ERROR on all ok, ER status( or ER_FAILED) otherwise * value(in/out): a db_value * Note: if value is an OID then turn it into an OBJECT type value * if value is a VOBJ then turn it into a vmop * if value is a set/seq then do same fixups on its elements */ static int cursor_fixup_vobjs (DB_VALUE * value_p) { DB_OBJECT *obj; int rc; switch (DB_VALUE_DOMAIN_TYPE (value_p)) { case DB_TYPE_OID: rc = vid_oid_to_object (value_p, &obj); DB_MAKE_OBJECT (value_p, obj); break; case DB_TYPE_VOBJ: if (DB_IS_NULL (value_p)) { db_value_clear (value_p); db_value_domain_init (value_p, DB_TYPE_OBJECT, DB_DEFAULT_PRECISION, DB_DEFAULT_SCALE); rc = NO_ERROR; } else { rc = vid_vobj_to_object (value_p, &obj); pr_clear_value (value_p); DB_MAKE_OBJECT (value_p, obj); } break; case DB_TYPE_SET: case DB_TYPE_MULTISET: case DB_TYPE_SEQUENCE: /* fixup any set/seq of vobjs into a set/seq of vmops */ rc = cursor_fixup_set_vobjs (value_p); break; default: rc = NO_ERROR; break; } return rc; }
/* * cursor_print_list () - Dump the content of the list file to the standard output * return: * query_id(in): * list_id(in): List File Identifier */ void cursor_print_list (QUERY_ID query_id, QFILE_LIST_ID * list_id_p) { CURSOR_ID cursor_id; DB_VALUE *value_list_p, *value_p; int count, i, status; count = list_id_p->type_list.type_cnt; value_list_p = (DB_VALUE *) malloc (count * sizeof (DB_VALUE)); if (value_list_p == NULL) { return; } fprintf (stdout, "\n================= Q U E R Y R E S U L T S =================\n\n"); if (cursor_open (&cursor_id, list_id_p, false, false) == false) { free_and_init (value_list_p); return; } cursor_id.query_id = query_id; while (true) { status = cursor_next_tuple (&cursor_id); if (status != DB_CURSOR_SUCCESS) { break; } if (cursor_get_tuple_value_list (&cursor_id, count, value_list_p) != NO_ERROR) { goto cleanup; } fprintf (stdout, "\n "); for (i = 0, value_p = value_list_p; i < count; i++, value_p++) { fprintf (stdout, " "); if (DB_VALUE_TYPE (value_p) == DB_TYPE_SET || DB_VALUE_TYPE (value_p) == DB_TYPE_MULTISET || DB_VALUE_TYPE (value_p) == DB_TYPE_SEQUENCE || DB_VALUE_TYPE (value_p) == DB_TYPE_VOBJ) { db_set_print (DB_GET_SET (value_p)); } else { db_value_print (value_p); } db_value_clear (value_p); fprintf (stdout, " "); } } fprintf (stdout, "\n"); cleanup: cursor_close (&cursor_id); free_and_init (value_list_p); return; }
/* * set_to_string() - convert set value to string * return: formatted string * value(in): set value to convert * begin_notation(in): character to use to denote begin of set * end_notation(in): character to use to denote end of set * max_entries(in): maximum number of entries to convert. -1 for all * plain_string(in): refine string for plain output */ static char * set_to_string (DB_VALUE * value, char begin_notation, char end_notation, int max_entries, bool plain_string) { int cardinality, total_string_length, i; char **string_array; char *return_string = NULL; DB_VALUE element; int set_error; DB_SET *set; set = DB_GET_SET (value); if (set == NULL) { return (NULL); } /* pre-fetch any objects in the set, this will prevent multiple server calls during set rendering */ db_fetch_set (set, DB_FETCH_READ, 0); /* formerly we filtered out deleted elements here, now just use db_set_size to get the current size, including NULL & * deleted elements */ cardinality = db_set_size (set); if (cardinality < 0) { return (NULL); } else if (cardinality == 0) { char temp_buffer[4]; i = 0; if (begin_notation != '\0') { temp_buffer[i++] = begin_notation; } if (end_notation != '\0') { temp_buffer[i++] = end_notation; } temp_buffer[i] = '\0'; return (duplicate_string ((const char *) &(temp_buffer[0]))); } if (max_entries != -1 && max_entries < cardinality) { cardinality = max_entries; } string_array = (char **) malloc ((cardinality + 2) * sizeof (char *)); if (string_array == NULL) { return (NULL); } memset (string_array, 0, (cardinality + 2) * sizeof (char *)); total_string_length = cardinality * 2; for (i = 0; i < cardinality; i++) { set_error = db_set_get (set, i, &element); if (set_error != NO_ERROR) { goto finalize; } string_array[i] = csql_db_value_as_string (&element, NULL, plain_string); db_value_clear (&element); if (string_array[i] == NULL) { string_array[i] = duplicate_string ("NULL"); if (string_array[i] == NULL) { goto finalize; } } total_string_length += strlen (string_array[i]); } /* for (i = 0; i < cardinality... */ return_string = (char *) malloc (total_string_length + 4); if (return_string == NULL) { goto finalize; } if (begin_notation != '\0') { (void) sprintf (return_string, "%c%s", begin_notation, string_array[0]); } else { (void) strcpy (return_string, string_array[0]); } for (i = 1; i < cardinality; i++) { (void) strcat (return_string, ", "); (void) strcat (return_string, string_array[i]); } if (end_notation != '\0') { int len = strlen (return_string); return_string[len++] = end_notation; return_string[len] = '\0'; } finalize: for (i = 0; i < cardinality; i++) { if (string_array[i] == NULL) { break; } free_and_init (string_array[i]); } free_and_init (string_array); return return_string; }