Example #1
0
/*
 * Create partitions and return an OID of the partition that contain value
 */
Oid
create_partitions(Oid relid, Datum value, Oid value_type, bool *crashed)
{
	int 		ret;
	RangeEntry *ranges;
	Datum		vals[2];
	Oid			oids[] = {OIDOID, value_type};
	bool		nulls[] = {false, false};
	char	   *sql;
	bool		found;
	int pos;
	PartRelationInfo *prel;
	RangeRelation	*rangerel;
	FmgrInfo   cmp_func;
	char *schema;

	*crashed = false;
	schema = get_extension_schema();

	prel = get_pathman_relation_info(relid, NULL);
	rangerel = get_pathman_range_relation(relid, NULL);
	ranges = dsm_array_get_pointer(&rangerel->ranges);

	/* Comparison function */
	cmp_func = *get_cmp_func(value_type, prel->atttype);

	vals[0] = ObjectIdGetDatum(relid);
	vals[1] = value;

	/* Perform PL procedure */
	sql = psprintf("SELECT %s.append_partitions_on_demand_internal($1, $2)",
				   schema);
	PG_TRY();
	{
		ret = SPI_execute_with_args(sql, 2, oids, vals, nulls, false, 0);
		if (ret > 0)
		{
			/* Update relation info */
			free_dsm_array(&rangerel->ranges);
			free_dsm_array(&prel->children);
			load_check_constraints(relid, GetCatalogSnapshot(relid));
		}
	}
	PG_CATCH();
	{
		elog(WARNING, "Attempt to create new partitions failed");
		if (crashed != NULL)
			*crashed = true;
		return 0;
	}
	PG_END_TRY();

	/* Repeat binary search */
	ranges = dsm_array_get_pointer(&rangerel->ranges);
	pos = range_binary_search(rangerel, &cmp_func, value, &found);
	if (found)
		return ranges[pos].child_oid;

	return 0;
}
Example #2
0
    bool search(vector<int>& nums, int target) {
        int min_index = find_min_index(nums);
        printf("%d\n", min_index);
        int target_index = -1;
        if (min_index == 0) {
            target_index = range_binary_search(nums, 0, nums.size() - 1, target);
        } else {
            if (nums[0] <= target && target <= nums[min_index - 1]) {
               target_index = range_binary_search(nums, 0, min_index - 1, target);
            } else if (nums[min_index] <= target && target <= nums[nums.size() - 1]) {
               target_index = range_binary_search(nums, min_index, nums.size() - 1, target);
            } 
        }

        return target_index != -1; 

    }
Example #3
0
/*
 * Returns partition oid for specified parent relid and value.
 * In case when partition isn't exist try to create one.
 */
Datum
find_or_create_range_partition(PG_FUNCTION_ARGS)
{
	int		relid = DatumGetInt32(PG_GETARG_DATUM(0));
	Datum	value = PG_GETARG_DATUM(1);
	Oid		value_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
	int		pos;
	bool	found;
	RangeRelation	*rangerel;
	RangeEntry		*ranges;
	TypeCacheEntry	*tce;
	PartRelationInfo *prel;
	Oid				 cmp_proc_oid;
	FmgrInfo		 cmp_func;

	tce = lookup_type_cache(value_type,
		TYPECACHE_EQ_OPR | TYPECACHE_LT_OPR | TYPECACHE_GT_OPR |
		TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO);

	prel = get_pathman_relation_info(relid, NULL);
	rangerel = get_pathman_range_relation(relid, NULL);

	if (!prel || !rangerel)
		PG_RETURN_NULL();

	cmp_proc_oid = get_opfamily_proc(tce->btree_opf,
									 value_type,
									 prel->atttype,
									 BTORDER_PROC);
	fmgr_info(cmp_proc_oid, &cmp_func);

	ranges = dsm_array_get_pointer(&rangerel->ranges);
	pos = range_binary_search(rangerel, &cmp_func, value, &found);

	/*
	 * If found then just return oid. Else create new partitions
	 */
	if (found)
		PG_RETURN_OID(ranges[pos].child_oid);
	/*
	 * If not found and value is between first and last partitions
	*/
	if (!found && pos >= 0)
		PG_RETURN_NULL();
	else
	{
		Oid		child_oid;
		bool	crashed = false;

		/* Lock config before appending new partitions */
		LWLockAcquire(pmstate->load_config_lock, LW_EXCLUSIVE);

		/* Restrict concurrent partition creation */
		LWLockAcquire(pmstate->edit_partitions_lock, LW_EXCLUSIVE);

		/*
		 * Check if someone else has already created partition.
		 */
		ranges = dsm_array_get_pointer(&rangerel->ranges);
		pos = range_binary_search(rangerel, &cmp_func, value, &found);
		if (found)
		{
			LWLockRelease(pmstate->edit_partitions_lock);
			LWLockRelease(pmstate->load_config_lock);
			PG_RETURN_OID(ranges[pos].child_oid);
		}

		/* Start background worker to create new partitions */
		child_oid = create_partitions_bg_worker(relid, value, value_type, &crashed);

		// SPI_connect();
		// child_oid = create_partitions(relid, value, value_type, &crashed);
		// SPI_finish();
		// elog(WARNING, "Worker finished");

		/* Release locks */
		if (!crashed)
		{
			LWLockRelease(pmstate->edit_partitions_lock);
			LWLockRelease(pmstate->load_config_lock);
		}

		/* Repeat binary search */
		ranges = dsm_array_get_pointer(&rangerel->ranges);
		pos = range_binary_search(rangerel, &cmp_func, value, &found);
		if (found)
			PG_RETURN_OID(child_oid);
	}

	PG_RETURN_NULL();
}