示例#1
0
/*
 * 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);
}
示例#2
0
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);
}
示例#3
0
/*
 * 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;
}
示例#4
0
/*
 * 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;
}
示例#5
0
/*
 * 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;
}
示例#6
0
/*
 * 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;
}