예제 #1
0
static void do_add (bool_t play, char * * title)
{
    int list = aud_playlist_by_unique_id (playlist_id);
    int n_items = index_count (items);
    int n_selected = 0;

    Index * filenames = index_new ();
    Index * tuples = index_new ();

    for (int i = 0; i < n_items; i ++)
    {
        if (! selection->data[i])
            continue;

        Item * item = index_get (items, i);

        for (int m = 0; m < item->matches->len; m ++)
        {
            int entry = g_array_index (item->matches, int, m);
            index_insert (filenames, -1, aud_playlist_entry_get_filename (list, entry));
            index_insert (tuples, -1, aud_playlist_entry_get_tuple (list, entry, TRUE));
        }

        n_selected ++;
        if (title && n_selected == 1)
            * title = item->name;
    }

    if (title && n_selected != 1)
        * title = NULL;

    aud_playlist_entry_insert_batch (aud_playlist_get_active (), -1, filenames,
     tuples, play);
}
예제 #2
0
static void open_modules_for_path (const char * path)
{
    GDir * folder = g_dir_open (path, 0, NULL);
    if (! folder)
    {
        fprintf (stderr, "ladspa: Failed to read folder %s: %s\n", path, strerror (errno));
        return;
    }

    const char * name;
    while ((name = g_dir_read_name (folder)))
    {
        if (! str_has_suffix_nocase (name, G_MODULE_SUFFIX))
            continue;

        char * filename = filename_build (path, name);
        void * handle = open_module (filename);

        if (handle)
            index_insert (modules, -1, handle);

        str_unref (filename);
    }

    g_dir_close (folder);
}
예제 #3
0
static PluginData * open_plugin (const char * path, const LADSPA_Descriptor * desc)
{
    const char * slash = strrchr (path, G_DIR_SEPARATOR);
    g_return_val_if_fail (slash && slash[1], NULL);
    g_return_val_if_fail (desc->Label && desc->Name, NULL);

    PluginData * plugin = g_slice_new (PluginData);
    plugin->path = g_strdup (slash + 1);
    plugin->desc = desc;
    plugin->controls = index_new ();
    plugin->in_ports = g_array_new (0, 0, sizeof (int));
    plugin->out_ports = g_array_new (0, 0, sizeof (int));
    plugin->selected = 0;

    for (int i = 0; i < desc->PortCount; i ++)
    {
        if (LADSPA_IS_PORT_CONTROL (desc->PortDescriptors[i]))
        {
            ControlData * control = parse_control (desc, i);
            if (control)
                index_insert (plugin->controls, -1, control);
        }
        else if (LADSPA_IS_PORT_AUDIO (desc->PortDescriptors[i]) &&
         LADSPA_IS_PORT_INPUT (desc->PortDescriptors[i]))
            g_array_append_val (plugin->in_ports, i);
        else if (LADSPA_IS_PORT_AUDIO (desc->PortDescriptors[i]) &&
         LADSPA_IS_PORT_OUTPUT (desc->PortDescriptors[i]))
            g_array_append_val (plugin->out_ports, i);
    }

    return plugin;
}
예제 #4
0
void PPSWorkload::init_tab_suppliers() {
  char * padding = new char[100];
  for (int i = 0; i < 100; i++) {
    padding[i] = 'z';
  }
  for (UInt32 id = 1; id <= g_max_supplier_key; id++) {
    if (GET_NODE_ID(suppliers_to_partition(id)) != g_node_id) 
      continue;
		row_t * row;
		uint64_t row_id;
    t_suppliers->get_new_row(row, 0, row_id);
    row->set_primary_key(id);
    row->set_value(0,id);
    row->set_value(FIELD1,padding);
    row->set_value(FIELD2,padding);
    row->set_value(FIELD3,padding);
    row->set_value(FIELD4,padding);
    row->set_value(FIELD5,padding);
    row->set_value(FIELD6,padding);
    row->set_value(FIELD7,padding);
    row->set_value(FIELD8,padding);
    row->set_value(FIELD9,padding);
    row->set_value(FIELD10,padding);
    
		index_insert(i_suppliers, id, row, suppliers_to_partition(id));

  }
}
예제 #5
0
static void search_cb (void * key, void * _item, void * _state)
{
    Item * item = _item;
    SearchState * state = _state;

    if (index_count (state->items[item->field]) > MAX_RESULTS)
        return;

    int oldmask = state->mask;
    int count = index_count (search_terms);

    for (int t = 0, bit = 1; t < count; t ++, bit <<= 1)
    {
        if (! (state->mask & bit))
            continue; /* skip term if it is already found */

        if (strstr (item->folded, index_get (search_terms, t)))
            state->mask &= ~bit; /* we found it */
        else if (! item->children)
            break; /* quit early if there are no children to search */
    }

    if (! state->mask)
        index_insert (state->items[item->field], -1, item);

    if (item->children)
        g_hash_table_foreach (item->children, search_cb, state);

    state->mask = oldmask;
}
예제 #6
0
void PPSWorkload::init_tab_products() {
  char * padding = new char[100];
  for (int i = 0; i < 100; i++) {
    padding[i] = 'z';
  }
  for (UInt32 id = 1; id <= g_max_product_key; id++) {
    if (GET_NODE_ID(products_to_partition(id)) != g_node_id) 
      continue;
		row_t * row;
		uint64_t row_id;
    t_products->get_new_row(row, 0, row_id);
    row->set_primary_key(id);
    row->set_value(0,id);
    row->set_value(FIELD1,padding);
    row->set_value(FIELD2,padding);
    row->set_value(FIELD3,padding);
    row->set_value(FIELD4,padding);
    row->set_value(FIELD5,padding);
    row->set_value(FIELD6,padding);
    row->set_value(FIELD7,padding);
    row->set_value(FIELD8,padding);
    row->set_value(FIELD9,padding);
    row->set_value(FIELD10,padding);
    
		index_insert(i_products, id, row, products_to_partition(id));
    DEBUG("PRODUCTS added (%d, ...)\n",id);

  }
}
예제 #7
0
/*
 * _bitmap_insert_lov() -- insert a new data into the given heap and index.
 */
void
_bitmap_insert_lov(Relation lovHeap, Relation lovIndex, Datum *datum,
				   bool *nulls, bool use_wal __attribute__((unused)))
{
	TupleDesc	tupDesc;
	HeapTuple	tuple;
	bool		result;
	Datum	   *indexDatum;
	bool	   *indexNulls;

	tupDesc = RelationGetDescr(lovHeap);

	/* insert this tuple into the heap */
	tuple = heap_form_tuple(tupDesc, datum, nulls);
	frozen_heap_insert(lovHeap, tuple);

	/* insert a new tuple into the index */
	indexDatum = palloc0((tupDesc->natts - 2) * sizeof(Datum));
	indexNulls = palloc0((tupDesc->natts - 2) * sizeof(bool));
	memcpy(indexDatum, datum, (tupDesc->natts - 2) * sizeof(Datum));
	memcpy(indexNulls, nulls, (tupDesc->natts - 2) * sizeof(bool));
	result = index_insert(lovIndex, indexDatum, indexNulls,
					 	  &(tuple->t_self), lovHeap, true);

	pfree(indexDatum);
	pfree(indexNulls);
	Assert(result);

	heap_freetuple(tuple);
}
예제 #8
0
void tpcc_wl::init_tab_dist(uint64_t wid) {
	for (uint64_t did = 1; did <= DIST_PER_WARE; did++) {
		row_t * row;
		uint64_t row_id;
		t_district->get_new_row(row, 0, row_id);
		row->set_primary_key(did);
		
		row->set_value(D_ID, did);
		row->set_value(D_W_ID, wid);
		char name[10];
		MakeAlphaString(6, 10, name);
		row->set_value(D_NAME, name);
		char street[20];
        MakeAlphaString(10, 20, street);
		row->set_value(D_STREET_1, street);
        MakeAlphaString(10, 20, street);
		row->set_value(D_STREET_2, street);
        MakeAlphaString(10, 20, street);
		row->set_value(D_CITY, street);
		char state[2];
		MakeAlphaString(2, 2, state); /* State */
		row->set_value(D_STATE, state);
		char zip[9];
    	MakeNumberString(9, 9, zip); /* Zip */
		row->set_value(D_ZIP, zip);
    	double tax = (double)URand(0L,200L)/1000.0;
    	double w_ytd=30000.00;
		row->set_value(D_TAX, tax);
		row->set_value(D_YTD, w_ytd);
		row->set_value(D_NEXT_O_ID, 3001);
		
		index_insert(i_district, distKey(did, wid), row, wh_to_part(wid));
	}
}
예제 #9
0
static void * open_module (const char * path)
{
    GModule * handle = g_module_open (path, G_MODULE_BIND_LOCAL);
    if (! handle)
    {
        fprintf (stderr, "ladspa: Failed to open module %s: %s\n", path, g_module_error ());
        return NULL;
    }

    void * sym;
    if (! g_module_symbol (handle, "ladspa_descriptor", & sym))
    {
        fprintf (stderr, "ladspa: Not a valid LADSPA module: %s\n", path);
        g_module_close (handle);
        return NULL;
    }

    LADSPA_Descriptor_Function descfun = (LADSPA_Descriptor_Function) sym;

    const LADSPA_Descriptor * desc;
    for (int i = 0; (desc = descfun (i)); i ++)
    {
        PluginData * plugin = open_plugin (path, desc);
        if (plugin)
            index_insert (plugins, -1, plugin);
    }

    return handle;
}
예제 #10
0
LoadedPlugin * enable_plugin_locked (PluginData * plugin)
{
    LoadedPlugin * loaded = g_slice_new (LoadedPlugin);
    loaded->plugin = plugin;
    loaded->selected = 0;

    int count = index_count (plugin->controls);
    loaded->values = g_malloc (sizeof (float) * count);

    for (int i = 0; i < count; i ++)
    {
        ControlData * control = index_get (plugin->controls, i);
        loaded->values[i] = control->def;
    }

    loaded->active = 0;
    loaded->instances = NULL;
    loaded->in_bufs = NULL;
    loaded->out_bufs = NULL;

    loaded->settings_win = NULL;

    index_insert (loadeds, -1, loaded);
    return loaded;
}
예제 #11
0
파일: tpcc_wl.cpp 프로젝트: apavlo/DBx1000
void tpcc_wl::init_tab_wh(uint32_t wid) {
	assert(wid >= 1 && wid <= g_num_wh);
	row_t * row;
	uint64_t row_id;
	t_warehouse->get_new_row(row, 0, row_id);
	row->set_primary_key(wid);

	row->set_value(W_ID, wid);
	char name[10];
    MakeAlphaString(6, 10, name, wid-1);
	row->set_value(W_NAME, name);
	char street[20];
    MakeAlphaString(10, 20, street, wid-1);
	row->set_value(W_STREET_1, street);
    MakeAlphaString(10, 20, street, wid-1);
	row->set_value(W_STREET_2, street);
    MakeAlphaString(10, 20, street, wid-1);
	row->set_value(W_CITY, street);
	char state[2];
	MakeAlphaString(2, 2, state, wid-1); /* State */
	row->set_value(W_STATE, state);
	char zip[9];
   	MakeNumberString(9, 9, zip, wid-1); /* Zip */
	row->set_value(W_ZIP, zip);
   	double tax = (double)URand(0L,200L,wid-1)/1000.0;
   	double w_ytd=300000.00;
	row->set_value(W_TAX, tax);
	row->set_value(W_YTD, w_ytd);
	
	index_insert(i_warehouse, wid, row, wh_to_part(wid));
	return;
}
예제 #12
0
파일: index.c 프로젝트: boyski/libgit2
int git_index_append(git_index *index, const char *path, int stage)
{
	int error;
	git_index_entry entry;

	if ((error = index_init_entry(&entry, index, path, stage)) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to append to index");

	return index_insert(index, &entry, 0);
}
예제 #13
0
static void shift_rows (void * user, int row, int before)
{
    int rows = index_count (user);
    g_return_if_fail (row >= 0 && row < rows);
    g_return_if_fail (before >= 0 && before <= rows);

    if (before == row)
        return;

    Index * move = index_new ();
    Index * others = index_new ();

    int begin, end;
    if (before < row)
    {
        begin = before;
        end = row + 1;
        while (end < rows && ((Column *) index_get (user, end))->selected)
            end ++;
    }
    else
    {
        begin = row;
        while (begin > 0 && ((Column *) index_get (user, begin - 1))->selected)
            begin --;
        end = before;
    }

    for (int i = begin; i < end; i ++)
    {
        Column * c = index_get (user, i);
        index_insert (c->selected ? move : others, -1, c);
    }

    if (before < row)
    {
        index_copy_insert (others, 0, move, -1, -1);
        index_free (others);
    }
    else
    {
        index_copy_insert (move, 0, others, -1, -1);
        index_free (move);
        move = others;
    }

    index_copy_set (move, 0, user, begin, end - begin);
    index_free (move);

    GtkWidget * list = (user == chosen) ? chosen_list : avail_list;
    audgui_list_update_rows (list, begin, end - begin);
    audgui_list_update_selection (list, begin, end - begin);
}
예제 #14
0
/*
 * ExecInsertCQMatRelIndexTuples
 *
 * This is a trimmed-down version of ExecInsertIndexTuples
 */
void
ExecInsertCQMatRelIndexTuples(ResultRelInfo *indstate, TupleTableSlot *slot, EState *estate)
{
	int			i;
	int			numIndexes;
	RelationPtr relationDescs;
	Relation	heapRelation;
	IndexInfo **indexInfoArray;
	Datum		values[INDEX_MAX_KEYS];
	bool		isnull[INDEX_MAX_KEYS];
	HeapTuple tup;

	/* bail if there are no indexes to update */
	numIndexes = indstate->ri_NumIndices;
	if (numIndexes == 0)
		return;

	tup = ExecMaterializeSlot(slot);

	/* HOT update does not require index inserts */
	if (HeapTupleIsHeapOnly(tup))
		return;

	relationDescs = indstate->ri_IndexRelationDescs;
	indexInfoArray = indstate->ri_IndexRelationInfo;
	heapRelation = indstate->ri_RelationDesc;

	/*
	 * for each index, form and insert the index tuple
	 */
	for (i = 0; i < numIndexes; i++)
	{
		IndexInfo  *indexInfo;

		indexInfo = indexInfoArray[i];

		/* If the index is marked as read-only, ignore it */
		if (!indexInfo->ii_ReadyForInserts)
			continue;

		/* Index expressions need an EState to be eval'd in */
		if (indexInfo->ii_Expressions)
		{
			ExprContext *econtext = GetPerTupleExprContext(estate);
			econtext->ecxt_scantuple = slot;
		}

		FormIndexDatum(indexInfo, slot, estate, values, isnull);

		index_insert(relationDescs[i], values, isnull, &(tup->t_self),
				heapRelation, relationDescs[i]->rd_index->indisunique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO);
	}
}
예제 #15
0
void pw_col_save (void)
{
    Index * index = index_new ();

    for (int i = 0; i < pw_num_cols; i ++)
        index_insert (index, -1, (void *) pw_col_keys[pw_cols[i]]);

    char * columns = index_to_str_list (index, " ");
    aud_set_str ("gtkui", "playlist_columns", columns);
    str_unref (columns);

    index_free (index);
}
예제 #16
0
static void begin_add (const char * path)
{
    int list = get_playlist (FALSE, FALSE);

    if (list < 0)
        list = create_playlist ();

    aud_set_str ("search-tool", "path", path);

    char * uri = filename_to_uri (path);
    g_return_if_fail (uri);

    if (! g_str_has_suffix (uri, "/"))
    {
        SCONCAT2 (temp, uri, "/");
        str_unref (uri);
        uri = str_get (temp);
    }

    destroy_added_table ();

    added_table = g_hash_table_new_full ((GHashFunc) str_hash, (GEqualFunc)
     str_equal, (GDestroyNotify) str_unref, NULL);

    int entries = aud_playlist_entry_count (list);

    for (int entry = 0; entry < entries; entry ++)
    {
        char * filename = aud_playlist_entry_get_filename (list, entry);

        if (g_str_has_prefix (filename, uri) && ! g_hash_table_contains (added_table, filename))
        {
            aud_playlist_entry_set_selected (list, entry, FALSE);
            g_hash_table_insert (added_table, filename, NULL);
        }
        else
        {
            aud_playlist_entry_set_selected (list, entry, TRUE);
            str_unref (filename);
        }
    }

    aud_playlist_delete_selected (list);
    aud_playlist_remove_failed (list);

    Index * add = index_new ();
    index_insert (add, -1, uri);
    aud_playlist_entry_insert_filtered (list, -1, add, NULL, filter_cb, NULL, FALSE);

    adding = TRUE;
}
예제 #17
0
파일: yidb.c 프로젝트: hardeasy/yidb
int set(char *key,char *value,int exptime){
	//store save
	int fieldId = 0;
	long blockPos;

	//printf("store_save \n");

	store_save(key,value,exptime,&fieldId,&blockPos);

	//printf("store return fieldId:%d,blockPos:%d\n", fieldId,blockPos);
	//index
	index_insert(key,fieldId,blockPos);

	return 0;
}
예제 #18
0
static int fulltextUpdate(sqlite3_vtab *pVtab, int nArg, sqlite3_value **ppArg,
                   sqlite_int64 *pRowid){
  fulltext_vtab *v = (fulltext_vtab *) pVtab;

  if( nArg<2 ){
    return index_delete(v, sqlite3_value_int64(ppArg[0]));
  }

  if( sqlite3_value_type(ppArg[0]) != SQLITE_NULL ){
    return SQLITE_ERROR;   /* an update; not yet supported */
  }

  assert( nArg==3 );    /* ppArg[1] = rowid, ppArg[2] = content */
  return index_insert(v, ppArg[1],
                      (const char *)sqlite3_value_text(ppArg[2]), pRowid);
}
예제 #19
0
static void equalizerwin_save_preset (Index * list, const char * name,
                                      const char * filename)
{
    int p = equalizerwin_find_preset (list, name);
    EqualizerPreset * preset = (p >= 0) ? index_get (list, p) : NULL;

    if (! preset)
    {
        preset = aud_equalizer_preset_new (name);
        index_insert (list, -1, preset);
    }

    equalizerwin_update_preset (preset);

    aud_equalizer_write_presets (list, filename);
}
예제 #20
0
파일: tpcc_wl.cpp 프로젝트: apavlo/DBx1000
// TODO ITEM table is assumed to be in partition 0
void tpcc_wl::init_tab_item() {
	for (UInt32 i = 1; i <= g_max_items; i++) {
		row_t * row;
		uint64_t row_id;
		t_item->get_new_row(row, 0, row_id);
		row->set_primary_key(i);
		row->set_value(I_ID, i);
		row->set_value(I_IM_ID, URand(1L,10000L, 0));
		char name[24];
		MakeAlphaString(14, 24, name, 0);
		row->set_value(I_NAME, name);
		row->set_value(I_PRICE, URand(1, 100, 0));
		char data[50];
    	MakeAlphaString(26, 50, data, 0);
		// TODO in TPCC, "original" should start at a random position
		if (RAND(10, 0) == 0) 
			strcpy(data, "original");		
		row->set_value(I_DATA, data);
		
		index_insert(i_item, i, row, 0);
	}
}
예제 #21
0
static void write_index(const char *filename)
{
	struct index_node *index;
	char *line;
	FILE *cfile;
	
	cfile = fopen(filename, "w");
	if (!cfile)
		fatal("Could not open %s for writing: %s\n",
		      filename, strerror(errno));
	
	index = index_create();
	
	while((line = getline_wrapped(stdin, NULL))) {
		index_insert(index, line);
		free(line);
	}
	
	index_write(index, cfile);
	index_destroy(index);
	fclose(cfile);
}
예제 #22
0
void tpcc_wl::init_tab_stock(uint64_t wid) {
	
	for (UInt32 sid = 1; sid <= g_max_items; sid++) {
		row_t * row;
		uint64_t row_id;
		t_stock->get_new_row(row, 0, row_id);
		row->set_primary_key(sid);
		row->set_value(S_I_ID, sid);
		row->set_value(S_W_ID, wid);
		row->set_value(S_QUANTITY, URand(10, 100));
		row->set_value(S_REMOTE_CNT, 0);
#if !TPCC_SMALL
		char s_dist[25];
		char row_name[10] = "S_DIST_";
		for (int i = 1; i <= 10; i++) {
			if (i < 10) {
				row_name[7] = '0';
				row_name[8] = i + '0';
			} else {
				row_name[7] = '1';
				row_name[8] = '0';
			}
			row_name[9] = '\0';
			MakeAlphaString(24, 24, s_dist);
			row->set_value(row_name, s_dist);
		}
		row->set_value(S_YTD, 0);
		row->set_value(S_ORDER_CNT, 0);
		char s_data[50];
		int len = MakeAlphaString(26, 50, s_data);
		if (rand() % 100 < 10) {
			int idx = URand(0, len - 8);
			strcpy(&s_data[idx], "original");
		}
		row->set_value(S_DATA, s_data);
#endif
		index_insert(i_stock, stockKey(sid, wid), row, wh_to_part(wid));
	}
}
예제 #23
0
static void transfer (Index * source)
{
    Index * dest;
    GtkWidget * source_list, * dest_list;
    if (source == chosen)
    {
        dest = avail;
        source_list = chosen_list;
        dest_list = avail_list;
    }
    else
    {
        dest = chosen;
        source_list = avail_list;
        dest_list = chosen_list;
    }

    int source_rows = index_count (source);
    int dest_rows = index_count (dest);

    for (int row = 0; row < source_rows; )
    {
        Column * c = index_get (source, row);
        if (! c->selected)
        {
            row ++;
            continue;
        }

        index_delete (source, row, 1);
        audgui_list_delete_rows (source_list, row, 1);
        source_rows --;
        index_insert (dest, -1, c);
        audgui_list_insert_rows (dest_list, dest_rows, 1);
        dest_rows ++;
    }
}
예제 #24
0
void tpcc_wl::init_tab_wh() {
	if (WL_VERB)
		printf("[init] workload table.\n");
	for (UInt32 wid = 1; wid <= g_num_wh; wid ++) {
		row_t * row;
		uint64_t row_id;
		t_warehouse->get_new_row(row, 0, row_id);
		row->set_primary_key(wid);

		row->set_value(W_ID, wid);
		char name[10];
        MakeAlphaString(6, 10, name);
		row->set_value(W_NAME, name);
		char street[20];
        MakeAlphaString(10, 20, street);
		row->set_value(W_STREET_1, street);
        MakeAlphaString(10, 20, street);
		row->set_value(W_STREET_2, street);
        MakeAlphaString(10, 20, street);
		row->set_value(W_CITY, street);
		char state[2];
		MakeAlphaString(2, 2, state); /* State */
		row->set_value(W_STATE, state);
		char zip[9];
    	MakeNumberString(9, 9, zip); /* Zip */
		row->set_value(W_ZIP, zip);
    	double tax = (double)URand(0L,200L)/1000.0;
    	double w_ytd=300000.00;
		row->set_value(W_TAX, tax);
		row->set_value(W_YTD, w_ytd);

		index_insert(i_warehouse, wid, row, wh_to_part(wid));
	}
	
	return;
}
예제 #25
0
/* ----------
 * toast_save_datum -
 *
 *	Save one single datum into the secondary relation and return
 *	a Datum reference for it.
 * ----------
 */
static Datum
toast_save_datum(Relation rel, Datum value, int options)
{
	Relation	toastrel;
	Relation	toastidx;
	HeapTuple	toasttup;
	TupleDesc	toasttupDesc;
	Datum		t_values[3];
	bool		t_isnull[3];
	CommandId	mycid = GetCurrentCommandId(true);
	struct varlena *result;
	struct varatt_external toast_pointer;
	struct
	{
		struct varlena hdr;
		char		data[TOAST_MAX_CHUNK_SIZE]; /* make struct big enough */
		int32		align_it;	/* ensure struct is aligned well enough */
	}			chunk_data;
	int32		chunk_size;
	int32		chunk_seq = 0;
	char	   *data_p;
	int32		data_todo;
	Pointer		dval = DatumGetPointer(value);

	/*
	 * Open the toast relation and its index.  We can use the index to check
	 * uniqueness of the OID we assign to the toasted item, even though it has
	 * additional columns besides OID.
	 */
	toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
	toasttupDesc = toastrel->rd_att;
	toastidx = index_open(toastrel->rd_rel->reltoastidxid, RowExclusiveLock);

	/*
	 * Get the data pointer and length, and compute va_rawsize and va_extsize.
	 *
	 * va_rawsize is the size of the equivalent fully uncompressed datum, so
	 * we have to adjust for short headers.
	 *
	 * va_extsize is the actual size of the data payload in the toast records.
	 */
	if (VARATT_IS_SHORT(dval))
	{
		data_p = VARDATA_SHORT(dval);
		data_todo = VARSIZE_SHORT(dval) - VARHDRSZ_SHORT;
		toast_pointer.va_rawsize = data_todo + VARHDRSZ;		/* as if not short */
		toast_pointer.va_extsize = data_todo;
	}
	else if (VARATT_IS_COMPRESSED(dval))
	{
		data_p = VARDATA(dval);
		data_todo = VARSIZE(dval) - VARHDRSZ;
		/* rawsize in a compressed datum is just the size of the payload */
		toast_pointer.va_rawsize = VARRAWSIZE_4B_C(dval) + VARHDRSZ;
		toast_pointer.va_extsize = data_todo;
		/* Assert that the numbers look like it's compressed */
		Assert(VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer));
	}
	else
	{
		data_p = VARDATA(dval);
		data_todo = VARSIZE(dval) - VARHDRSZ;
		toast_pointer.va_rawsize = VARSIZE(dval);
		toast_pointer.va_extsize = data_todo;
	}

	/*
	 * Insert the correct table OID into the result TOAST pointer.
	 *
	 * Normally this is the actual OID of the target toast table, but during
	 * table-rewriting operations such as CLUSTER, we have to insert the OID
	 * of the table's real permanent toast table instead.  rd_toastoid is set
	 * if we have to substitute such an OID.
	 */
	if (OidIsValid(rel->rd_toastoid))
		toast_pointer.va_toastrelid = rel->rd_toastoid;
	else
		toast_pointer.va_toastrelid = RelationGetRelid(toastrel);

	/*
	 * Choose an unused OID within the toast table for this toast value.
	 */
	toast_pointer.va_valueid = GetNewOidWithIndex(toastrel,
												  RelationGetRelid(toastidx),
												  (AttrNumber) 1);

	/*
	 * Initialize constant parts of the tuple data
	 */
	t_values[0] = ObjectIdGetDatum(toast_pointer.va_valueid);
	t_values[2] = PointerGetDatum(&chunk_data);
	t_isnull[0] = false;
	t_isnull[1] = false;
	t_isnull[2] = false;

	/*
	 * Split up the item into chunks
	 */
	while (data_todo > 0)
	{
		/*
		 * Calculate the size of this chunk
		 */
		chunk_size = Min(TOAST_MAX_CHUNK_SIZE, data_todo);

		/*
		 * Build a tuple and store it
		 */
		t_values[1] = Int32GetDatum(chunk_seq++);
		SET_VARSIZE(&chunk_data, chunk_size + VARHDRSZ);
		memcpy(VARDATA(&chunk_data), data_p, chunk_size);
		toasttup = heap_form_tuple(toasttupDesc, t_values, t_isnull);

		heap_insert(toastrel, toasttup, mycid, options, NULL);

		/*
		 * Create the index entry.	We cheat a little here by not using
		 * FormIndexDatum: this relies on the knowledge that the index columns
		 * are the same as the initial columns of the table.
		 *
		 * Note also that there had better not be any user-created index on
		 * the TOAST table, since we don't bother to update anything else.
		 */
		index_insert(toastidx, t_values, t_isnull,
					 &(toasttup->t_self),
					 toastrel,
					 toastidx->rd_index->indisunique ?
					 UNIQUE_CHECK_YES : UNIQUE_CHECK_NO);

		/*
		 * Free memory
		 */
		heap_freetuple(toasttup);

		/*
		 * Move on to next chunk
		 */
		data_todo -= chunk_size;
		data_p += chunk_size;
	}

	/*
	 * Done - close toast relation
	 */
	index_close(toastidx, RowExclusiveLock);
	heap_close(toastrel, RowExclusiveLock);

	/*
	 * Create the TOAST pointer value that we'll return
	 */
	result = (struct varlena *) palloc(TOAST_POINTER_SIZE);
	SET_VARSIZE_EXTERNAL(result, TOAST_POINTER_SIZE);
	memcpy(VARDATA_EXTERNAL(result), &toast_pointer, sizeof(toast_pointer));

	return PointerGetDatum(result);
}
예제 #26
0
파일: relation.c 프로젝트: 1uk3/contiki
db_result_t
relation_insert(relation_t *rel, attribute_value_t *values)
{
  attribute_t *attr;
  unsigned char record[rel->row_length];
  unsigned char *ptr;
  attribute_value_t *value;
  db_result_t result;

  value = values;

  PRINTF("DB: Relation %s has a record size of %u bytes\n",
	 rel->name, (unsigned)rel->row_length);
  ptr = record;

  PRINTF("DB: Insert (");

  for(attr = list_head(rel->attributes); attr != NULL; attr = attr->next, value++) {
    /* Verify that the value is in the expected domain. An exception
       to this rule is that INT may be promoted to LONG. */
    if(attr->domain != value->domain &&
       !(attr->domain == DOMAIN_LONG && value->domain == DOMAIN_INT)) {
      PRINTF("DB: The value domain %d does not match the domain %d of attribute %s\n",
             value->domain, attr->domain, attr->name);
      return DB_RELATIONAL_ERROR;
    }

    /* Set the data area for removed attributes to 0. */
    if(attr->flags & ATTRIBUTE_FLAG_INVALID) {
      memset(ptr, 0, attr->element_size);
      ptr += attr->element_size;
      continue;
    }

    result = db_value_to_phy((unsigned char *)ptr, attr, value);
    if(DB_ERROR(result)) {
      return result;
    }

#if DEBUG
    switch(attr->domain) {
    case DOMAIN_INT:
      PRINTF("%s=%d", attr->name, VALUE_INT(value));
      break;
    case DOMAIN_LONG:
      PRINTF("%s=%ld", attr->name, VALUE_LONG(value));
      break;
    case DOMAIN_STRING:
      PRINTF("%s='%s", attr->name, VALUE_STRING(value));
      break;
    default:
      PRINTF(")\nDB: Unhandled attribute domain: %d\n", attr->domain);
      return DB_TYPE_ERROR;
    }

    if(attr->next != NULL) {
      PRINTF(", ");
    }
#endif /* DEBUG */

    ptr += attr->element_size;
    if(attr->index != NULL) {
      if(DB_ERROR(index_insert(attr->index, value, rel->next_row))) {
        return DB_INDEX_ERROR;
      }
    }
  }

  PRINTF(")\n");

  rel->cardinality++;
  rel->next_row++;
  return storage_put_row(rel, record);
}
예제 #27
0
/* ----------
 * toast_save_datum -
 *
 *	Save one single datum into the secondary relation and return
 *	a varattrib reference for it.
 * ----------
 */
static Datum
toast_save_datum(Relation rel, Datum value)
{
	Relation	toastrel;
	Relation	toastidx;
	HeapTuple	toasttup;
	InsertIndexResult idxres;
	TupleDesc	toasttupDesc;
	Datum		t_values[3];
	char		t_nulls[3];
	varattrib  *result;
	struct
	{
		struct varlena hdr;
		char		data[TOAST_MAX_CHUNK_SIZE];
	}			chunk_data;
	int32		chunk_size;
	int32		chunk_seq = 0;
	char	   *data_p;
	int32		data_todo;

	/*
	 * Create the varattrib reference
	 */
	result = (varattrib *) palloc(sizeof(varattrib));

	result->va_header = sizeof(varattrib) | VARATT_FLAG_EXTERNAL;
	if (VARATT_IS_COMPRESSED(value))
	{
		result->va_header |= VARATT_FLAG_COMPRESSED;
		result->va_content.va_external.va_rawsize =
			((varattrib *) value)->va_content.va_compressed.va_rawsize;
	}
	else
		result->va_content.va_external.va_rawsize = VARATT_SIZE(value);

	result->va_content.va_external.va_extsize =
		VARATT_SIZE(value) - VARHDRSZ;
	result->va_content.va_external.va_valueid = newoid();
	result->va_content.va_external.va_toastrelid =
		rel->rd_rel->reltoastrelid;

	/*
	 * Initialize constant parts of the tuple data
	 */
	t_values[0] = ObjectIdGetDatum(result->va_content.va_external.va_valueid);
	t_values[2] = PointerGetDatum(&chunk_data);
	t_nulls[0] = ' ';
	t_nulls[1] = ' ';
	t_nulls[2] = ' ';

	/*
	 * Get the data to process
	 */
	data_p = VARATT_DATA(value);
	data_todo = VARATT_SIZE(value) - VARHDRSZ;

	/*
	 * Open the toast relation
	 */
	toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
	toasttupDesc = toastrel->rd_att;
	toastidx = index_open(toastrel->rd_rel->reltoastidxid);

	/*
	 * Split up the item into chunks
	 */
	while (data_todo > 0)
	{
		/*
		 * Calculate the size of this chunk
		 */
		chunk_size = Min(TOAST_MAX_CHUNK_SIZE, data_todo);

		/*
		 * Build a tuple and store it
		 */
		t_values[1] = Int32GetDatum(chunk_seq++);
		VARATT_SIZEP(&chunk_data) = chunk_size + VARHDRSZ;
		memcpy(VARATT_DATA(&chunk_data), data_p, chunk_size);
		toasttup = heap_formtuple(toasttupDesc, t_values, t_nulls);
		if (!HeapTupleIsValid(toasttup))
			elog(ERROR, "failed to build TOAST tuple");

		simple_heap_insert(toastrel, toasttup);

		/*
		 * Create the index entry.	We cheat a little here by not using
		 * FormIndexDatum: this relies on the knowledge that the index
		 * columns are the same as the initial columns of the table.
		 *
		 * Note also that there had better not be any user-created index on
		 * the TOAST table, since we don't bother to update anything else.
		 */
		idxres = index_insert(toastidx, t_values, t_nulls,
							  &(toasttup->t_self),
							  toastrel, toastidx->rd_index->indisunique);
		if (idxres == NULL)
			elog(ERROR, "failed to insert index entry for TOAST tuple");

		/*
		 * Free memory
		 */
		pfree(idxres);
		heap_freetuple(toasttup);

		/*
		 * Move on to next chunk
		 */
		data_todo -= chunk_size;
		data_p += chunk_size;
	}

	/*
	 * Done - close toast relation and return the reference
	 */
	index_close(toastidx);
	heap_close(toastrel, RowExclusiveLock);

	return PointerGetDatum(result);
}
예제 #28
0
/*
 * IndexSpoolInsert - 
 *
 *	Copy from ExecInsertIndexTuples.
 */
static void
IndexSpoolInsert(BTSpool **spools, TupleTableSlot *slot, ItemPointer tupleid, EState *estate, bool reindex)
{
	ResultRelInfo  *relinfo;
	int				i;
	int				numIndices;
	RelationPtr		indices;
	IndexInfo	  **indexInfoArray;
	Relation		heapRelation;
	ExprContext    *econtext;

	/*
	 * Get information from the result relation relinfo structure.
	 */
	relinfo = estate->es_result_relation_info;
	numIndices = relinfo->ri_NumIndices;
	indices = relinfo->ri_IndexRelationDescs;
	indexInfoArray = relinfo->ri_IndexRelationInfo;
	heapRelation = relinfo->ri_RelationDesc;

	/*
	 * We will use the EState's per-tuple context for evaluating predicates
	 * and index expressions (creating it if it's not already there).
	 */
	econtext = GetPerTupleExprContext(estate);

	/* Arrange for econtext's scan tuple to be the tuple under test */
	econtext->ecxt_scantuple = slot;

	for (i = 0; i < numIndices; i++)
	{
		Datum		values[INDEX_MAX_KEYS];
		bool		isnull[INDEX_MAX_KEYS];
		IndexInfo  *indexInfo;

		if (indices[i] == NULL)
			continue;

		/* Skip non-btree indexes on reindex mode. */
		if (reindex && spools != NULL && spools[i] == NULL)
			continue;

		indexInfo = indexInfoArray[i];

		/* If the index is marked as read-only, ignore it */
		if (!indexInfo->ii_ReadyForInserts)
			continue;

		/* Check for partial index */
		if (indexInfo->ii_Predicate != NIL)
		{
			List		   *predicate;

			/*
			 * If predicate state not set up yet, create it (in the estate's
			 * per-query context)
			 */
			predicate = indexInfo->ii_PredicateState;
			if (predicate == NIL)
			{
				predicate = (List *) ExecPrepareExpr((Expr *) indexInfo->ii_Predicate, estate);
				indexInfo->ii_PredicateState = predicate;
			}

			/* Skip this index-update if the predicate isn'loader satisfied */
			if (!ExecQual(predicate, econtext, false))
				continue;
		}

		FormIndexDatum(indexInfo, slot, estate, values, isnull);

		/*
		 * Insert or spool the tuple.
		 */
		if (spools != NULL && spools[i] != NULL)
		{
			IndexTuple itup = index_form_tuple(RelationGetDescr(indices[i]), values, isnull);
			itup->t_tid = *tupleid;
			_bt_spool(itup, spools[i]);
			pfree(itup);
		}
		else
		{
			/* Insert one by one */
			index_insert(indices[i], values, isnull, tupleid, heapRelation, indices[i]->rd_index->indisunique);
		}
	}
}
예제 #29
0
파일: indexing.c 프로젝트: markwkm/postgres
/*
 * CatalogIndexInsert - insert index entries for one catalog tuple
 *
 * This should be called for each inserted or updated catalog tuple.
 *
 * This is effectively a cut-down version of ExecInsertIndexTuples.
 */
void
CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
{
	int			i;
	int			numIndexes;
	RelationPtr relationDescs;
	Relation	heapRelation;
	TupleTableSlot *slot;
	IndexInfo **indexInfoArray;
	Datum		values[INDEX_MAX_KEYS];
	bool		isnull[INDEX_MAX_KEYS];

	/* HOT update does not require index inserts */
	if (HeapTupleIsHeapOnly(heapTuple))
		return;

	/*
	 * Get information from the state structure.  Fall out if nothing to do.
	 */
	numIndexes = indstate->ri_NumIndices;
	if (numIndexes == 0)
		return;
	relationDescs = indstate->ri_IndexRelationDescs;
	indexInfoArray = indstate->ri_IndexRelationInfo;
	heapRelation = indstate->ri_RelationDesc;

	/* Need a slot to hold the tuple being examined */
	slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
	ExecStoreTuple(heapTuple, slot, InvalidBuffer, false);

	/*
	 * for each index, form and insert the index tuple
	 */
	for (i = 0; i < numIndexes; i++)
	{
		IndexInfo  *indexInfo;

		indexInfo = indexInfoArray[i];

		/* If the index is marked as read-only, ignore it */
		if (!indexInfo->ii_ReadyForInserts)
			continue;

		/*
		 * Expressional and partial indexes on system catalogs are not
		 * supported, nor exclusion constraints, nor deferred uniqueness
		 */
		Assert(indexInfo->ii_Expressions == NIL);
		Assert(indexInfo->ii_Predicate == NIL);
		Assert(indexInfo->ii_ExclusionOps == NULL);
		Assert(relationDescs[i]->rd_index->indimmediate);

		/*
		 * FormIndexDatum fills in its values and isnull parameters with the
		 * appropriate values for the column(s) of the index.
		 */
		FormIndexDatum(indexInfo,
					   slot,
					   NULL,	/* no expression eval to do */
					   values,
					   isnull);

		/*
		 * The index AM does the rest.
		 */
		index_insert(relationDescs[i],	/* index relation */
					 values,	/* array of index Datums */
					 isnull,	/* is-null flags */
					 &(heapTuple->t_self),		/* tid of heap tuple */
					 heapRelation,
					 relationDescs[i]->rd_index->indisunique ?
					 UNIQUE_CHECK_YES : UNIQUE_CHECK_NO);
	}

	ExecDropSingleTupleTableSlot(slot);
}
예제 #30
0
/*
 * unique_key_recheck - trigger function to do a deferred uniqueness check.
 *
 * This now also does deferred exclusion-constraint checks, so the name is
 * somewhat historical.
 *
 * This is invoked as an AFTER ROW trigger for both INSERT and UPDATE,
 * for any rows recorded as potentially violating a deferrable unique
 * or exclusion constraint.
 *
 * This may be an end-of-statement check, a commit-time check, or a
 * check triggered by a SET CONSTRAINTS command.
 */
Datum
unique_key_recheck(PG_FUNCTION_ARGS)
{
	TriggerData *trigdata = (TriggerData *) fcinfo->context;
	const char *funcname = "unique_key_recheck";
	HeapTuple	new_row;
	ItemPointerData tmptid;
	Relation	indexRel;
	IndexInfo  *indexInfo;
	EState	   *estate;
	ExprContext *econtext;
	TupleTableSlot *slot;
	Datum		values[INDEX_MAX_KEYS];
	bool		isnull[INDEX_MAX_KEYS];

	/*
	 * Make sure this is being called as an AFTER ROW trigger.	Note:
	 * translatable error strings are shared with ri_triggers.c, so resist the
	 * temptation to fold the function name into them.
	 */
	if (!CALLED_AS_TRIGGER(fcinfo))
		ereport(ERROR,
				(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
				 errmsg("function \"%s\" was not called by trigger manager",
						funcname)));

	if (!TRIGGER_FIRED_AFTER(trigdata->tg_event) ||
		!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
		ereport(ERROR,
				(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
				 errmsg("function \"%s\" must be fired AFTER ROW",
						funcname)));

	/*
	 * Get the new data that was inserted/updated.
	 */
	if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
		new_row = trigdata->tg_trigtuple;
	else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
		new_row = trigdata->tg_newtuple;
	else
	{
		ereport(ERROR,
				(errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED),
				 errmsg("function \"%s\" must be fired for INSERT or UPDATE",
						funcname)));
		new_row = NULL;			/* keep compiler quiet */
	}

	/*
	 * If the new_row is now dead (ie, inserted and then deleted within our
	 * transaction), we can skip the check.  However, we have to be careful,
	 * because this trigger gets queued only in response to index insertions;
	 * which means it does not get queued for HOT updates.	The row we are
	 * called for might now be dead, but have a live HOT child, in which case
	 * we still need to make the check.  Therefore we have to use
	 * heap_hot_search, not just HeapTupleSatisfiesVisibility as is done in
	 * the comparable test in RI_FKey_check.
	 *
	 * This might look like just an optimization, because the index AM will
	 * make this identical test before throwing an error.  But it's actually
	 * needed for correctness, because the index AM will also throw an error
	 * if it doesn't find the index entry for the row.  If the row's dead then
	 * it's possible the index entry has also been marked dead, and even
	 * removed.
	 */
	tmptid = new_row->t_self;
	if (!heap_hot_search(&tmptid, trigdata->tg_relation, SnapshotSelf, NULL))
	{
		/*
		 * All rows in the HOT chain are dead, so skip the check.
		 */
		return PointerGetDatum(NULL);
	}

	/*
	 * Open the index, acquiring a RowExclusiveLock, just as if we were going
	 * to update it.  (This protects against possible changes of the index
	 * schema, not against concurrent updates.)
	 */
	indexRel = index_open(trigdata->tg_trigger->tgconstrindid,
						  RowExclusiveLock);
	indexInfo = BuildIndexInfo(indexRel);

	/*
	 * The heap tuple must be put into a slot for FormIndexDatum.
	 */
	slot = MakeSingleTupleTableSlot(RelationGetDescr(trigdata->tg_relation));

	ExecStoreTuple(new_row, slot, InvalidBuffer, false);

	/*
	 * Typically the index won't have expressions, but if it does we need an
	 * EState to evaluate them.  We need it for exclusion constraints too,
	 * even if they are just on simple columns.
	 */
	if (indexInfo->ii_Expressions != NIL ||
		indexInfo->ii_ExclusionOps != NULL)
	{
		estate = CreateExecutorState();
		econtext = GetPerTupleExprContext(estate);
		econtext->ecxt_scantuple = slot;
	}
	else
		estate = NULL;

	/*
	 * Form the index values and isnull flags for the index entry that we need
	 * to check.
	 *
	 * Note: if the index uses functions that are not as immutable as they are
	 * supposed to be, this could produce an index tuple different from the
	 * original.  The index AM can catch such errors by verifying that it
	 * finds a matching index entry with the tuple's TID.  For exclusion
	 * constraints we check this in check_exclusion_constraint().
	 */
	FormIndexDatum(indexInfo, slot, estate, values, isnull);

	/*
	 * Now do the appropriate check.
	 */
	if (indexInfo->ii_ExclusionOps == NULL)
	{
		/*
		 * Note: this is not a real insert; it is a check that the index entry
		 * that has already been inserted is unique.
		 */
		index_insert(indexRel, values, isnull, &(new_row->t_self),
					 trigdata->tg_relation, UNIQUE_CHECK_EXISTING);
	}
	else
	{
		/*
		 * For exclusion constraints we just do the normal check, but now it's
		 * okay to throw error.
		 */
		check_exclusion_constraint(trigdata->tg_relation, indexRel, indexInfo,
								   &(new_row->t_self), values, isnull,
								   estate, false, false);
	}

	/*
	 * If that worked, then this index entry is unique or non-excluded, and we
	 * are done.
	 */
	if (estate != NULL)
		FreeExecutorState(estate);

	ExecDropSingleTupleTableSlot(slot);

	index_close(indexRel, RowExclusiveLock);

	return PointerGetDatum(NULL);
}