mirror of https://github.com/citusdata/citus.git
[Columnar] Separate columnar from citus part1 - create columnar extension
parent
a40679139b
commit
9c67cb2e60
|
@ -0,0 +1,35 @@
|
|||
MODULE_big = columnar
|
||||
OBJS = mem_primitives_lib.o \
|
||||
memcpy_s.o \
|
||||
safe_str_constraint.o \
|
||||
safe_mem_constraint.o \
|
||||
ignore_handler_s.o \
|
||||
abort_handler_s.o \
|
||||
columnar.o \
|
||||
columnar_tableam.o \
|
||||
columnar_storage.o \
|
||||
columnar_compression.o \
|
||||
columnar_customscan.o \
|
||||
columnar_debug.o \
|
||||
columnar_metadata.o \
|
||||
columnar_reader.o \
|
||||
columnar_writer.o \
|
||||
mod.o \
|
||||
write_state_management.o
|
||||
|
||||
safestringlib_srcdir = $(citus_abs_top_srcdir)/vendor/safestringlib
|
||||
PG_CPPFLAGS += -I$(libpq_srcdir) -I$(safestringlib_srcdir)/include
|
||||
EXTENSION = columnar
|
||||
|
||||
DATA = $(wildcard sql/*--*.sql)
|
||||
REGRESS = columnar
|
||||
|
||||
ifdef USE_PGXS
|
||||
PG_CONFIG = pg_config
|
||||
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||
include $(PGXS)
|
||||
else
|
||||
subdir = src/backend/columnar
|
||||
top_builddir = ../../..
|
||||
include $(top_builddir)/Makefile.global
|
||||
endif
|
|
@ -0,0 +1,74 @@
|
|||
/*------------------------------------------------------------------
|
||||
* abort_handler_s.c
|
||||
*
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2012 Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "safeclib_private.h"
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* abort_handler_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_lib.h"
|
||||
* void abort_handler_s(const char *msg, void *ptr, errno_t error)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function writes a message on the standard error stream in
|
||||
* an implementation-defined format. The message shall include the
|
||||
* string pointed to by msg. The abort_handler_s function then calls
|
||||
* the abort function.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* msg Pointer to the message describing the error
|
||||
*
|
||||
* ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* Does not return to caller.
|
||||
*
|
||||
* ALSO SEE
|
||||
* ignore_handler_s()
|
||||
*
|
||||
*/
|
||||
|
||||
void abort_handler_s(const char *msg, void *ptr, errno_t error)
|
||||
{
|
||||
slprintf("ABORT CONSTRAINT HANDLER: (%u) %s\n", error,
|
||||
(msg) ? msg : "Null message");
|
||||
slabort();
|
||||
}
|
||||
EXPORT_SYMBOL(abort_handler_s)
|
|
@ -23,6 +23,8 @@
|
|||
#include "citus_version.h"
|
||||
#include "columnar/columnar.h"
|
||||
|
||||
PG_MODULE_MAGIC;
|
||||
|
||||
/* Default values for option parameters */
|
||||
#define DEFAULT_STRIPE_ROW_COUNT 150000
|
||||
#define DEFAULT_CHUNK_ROW_COUNT 10000
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
# Columnar extension
|
||||
comment = 'Columnar extension'
|
||||
default_version = '11.0-1'
|
||||
module_pathname = '$libdir/columnar'
|
||||
relocatable = false
|
||||
schema = pg_catalog
|
|
@ -171,7 +171,7 @@ columnar_beginscan(Relation relation, Snapshot snapshot,
|
|||
ParallelTableScanDesc parallel_scan,
|
||||
uint32 flags)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
int natts = relation->rd_att->natts;
|
||||
|
||||
|
@ -418,7 +418,7 @@ columnar_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan)
|
|||
static IndexFetchTableData *
|
||||
columnar_index_fetch_begin(Relation rel)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
Oid relfilenode = rel->rd_node.relNode;
|
||||
if (PendingWritesInUpperTransactions(relfilenode, GetCurrentSubTransactionId()))
|
||||
|
@ -643,7 +643,7 @@ static bool
|
|||
columnar_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot,
|
||||
Snapshot snapshot)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
uint64 rowNumber = tid_to_row_number(slot->tts_tid);
|
||||
StripeMetadata *stripeMetadata = FindStripeByRowNumber(rel, rowNumber, snapshot);
|
||||
|
@ -656,7 +656,7 @@ static TransactionId
|
|||
columnar_index_delete_tuples(Relation rel,
|
||||
TM_IndexDeleteOp *delstate)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
/*
|
||||
* XXX: We didn't bother implementing index_delete_tuple for neither of
|
||||
|
@ -717,7 +717,7 @@ static void
|
|||
columnar_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid,
|
||||
int options, BulkInsertState bistate)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
/*
|
||||
* columnar_init_write_state allocates the write state in a longer
|
||||
|
@ -765,7 +765,7 @@ static void
|
|||
columnar_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
|
||||
CommandId cid, int options, BulkInsertState bistate)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
ColumnarWriteState *writeState = columnar_init_write_state(relation,
|
||||
RelationGetDescr(relation),
|
||||
|
@ -841,7 +841,7 @@ columnar_relation_set_new_filenode(Relation rel,
|
|||
TransactionId *freezeXid,
|
||||
MultiXactId *minmulti)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
if (persistence == RELPERSISTENCE_UNLOGGED)
|
||||
{
|
||||
|
@ -878,7 +878,7 @@ columnar_relation_set_new_filenode(Relation rel,
|
|||
static void
|
||||
columnar_relation_nontransactional_truncate(Relation rel)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
RelFileNode relfilenode = rel->rd_node;
|
||||
|
||||
|
@ -926,7 +926,7 @@ columnar_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
|
|||
double *tups_vacuumed,
|
||||
double *tups_recently_dead)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
TupleDesc sourceDesc = RelationGetDescr(OldHeap);
|
||||
TupleDesc targetDesc = RelationGetDescr(NewHeap);
|
||||
|
@ -1024,14 +1024,14 @@ static void
|
|||
columnar_vacuum_rel(Relation rel, VacuumParams *params,
|
||||
BufferAccessStrategy bstrategy)
|
||||
{
|
||||
if (!CheckCitusVersion(WARNING))
|
||||
{
|
||||
/*
|
||||
* Skip if the extension catalogs are not up-to-date, but avoid
|
||||
* erroring during auto-vacuum.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
// if (!CheckCitusVersion(WARNING))
|
||||
// {
|
||||
// /*
|
||||
// * Skip if the extension catalogs are not up-to-date, but avoid
|
||||
// * erroring during auto-vacuum.
|
||||
// */
|
||||
// return;
|
||||
// }
|
||||
|
||||
/*
|
||||
* If metapage version of relation is older, then we hint users to VACUUM
|
||||
|
@ -1342,7 +1342,7 @@ columnar_index_build_range_scan(Relation columnarRelation,
|
|||
void *callback_state,
|
||||
TableScanDesc scan)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
if (start_blockno != 0 || numblocks != InvalidBlockNumber)
|
||||
{
|
||||
|
@ -1592,7 +1592,7 @@ columnar_index_validate_scan(Relation columnarRelation,
|
|||
ValidateIndexState *
|
||||
validateIndexState)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
// CheckCitusVersion(ERROR);
|
||||
|
||||
ColumnarReportTotalVirtualBlocks(columnarRelation, snapshot,
|
||||
PROGRESS_SCAN_BLOCKS_TOTAL);
|
||||
|
@ -1764,7 +1764,7 @@ TupleSortSkipSmallerItemPointers(Tuplesortstate *tupleSort, ItemPointer targetIt
|
|||
static uint64
|
||||
columnar_relation_size(Relation rel, ForkNumber forkNumber)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
uint64 nblocks = 0;
|
||||
|
||||
|
@ -1791,7 +1791,7 @@ columnar_relation_size(Relation rel, ForkNumber forkNumber)
|
|||
static bool
|
||||
columnar_relation_needs_toast_table(Relation rel)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1802,7 +1802,7 @@ columnar_estimate_rel_size(Relation rel, int32 *attr_widths,
|
|||
BlockNumber *pages, double *tuples,
|
||||
double *allvisfrac)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
RelationOpenSmgr(rel);
|
||||
*pages = smgrnblocks(rel->rd_smgr, MAIN_FORKNUM);
|
||||
|
@ -1975,7 +1975,7 @@ ColumnarTableDropHook(Oid relid)
|
|||
|
||||
if (IsColumnarTableAmTable(relid))
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
/*
|
||||
* Drop metadata. No need to drop storage here since for
|
||||
|
@ -2100,7 +2100,7 @@ ColumnarProcessUtility(PlannedStmt *pstmt,
|
|||
|
||||
if (rel->rd_tableam == GetColumnarTableAmRoutine())
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
if (!ColumnarSupportsIndexAM(indexStmt->accessMethod))
|
||||
{
|
||||
|
@ -2323,7 +2323,7 @@ PG_FUNCTION_INFO_V1(alter_columnar_table_set);
|
|||
Datum
|
||||
alter_columnar_table_set(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
Oid relationId = PG_GETARG_OID(0);
|
||||
|
||||
|
@ -2443,7 +2443,7 @@ PG_FUNCTION_INFO_V1(alter_columnar_table_reset);
|
|||
Datum
|
||||
alter_columnar_table_reset(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
//CheckCitusVersion(ERROR);
|
||||
|
||||
Oid relationId = PG_GETARG_OID(0);
|
||||
|
||||
|
@ -2507,6 +2507,21 @@ alter_columnar_table_reset(PG_FUNCTION_ARGS)
|
|||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the current user has owner rights to relationId, error out if
|
||||
* not. Superusers are regarded as owners.
|
||||
*/
|
||||
void
|
||||
EnsureTableOwner(Oid relationId)
|
||||
{
|
||||
if (!pg_class_ownercheck(relationId, GetUserId()))
|
||||
{
|
||||
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TABLE,
|
||||
get_rel_name(relationId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* upgrade_columnar_storage - upgrade columnar storage to the current
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*------------------------------------------------------------------
|
||||
* ignore_handler_s.c
|
||||
*
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2012 Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "safeclib_private.h"
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* ignore_handler_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_lib.h"
|
||||
* void ignore_handler_s(const char *msg, void *ptr, errno_t error)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function simply returns to the caller.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* msg Pointer to the message describing the error
|
||||
*
|
||||
* ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* Returns no value.
|
||||
*
|
||||
* ALSO SEE
|
||||
* abort_handler_s()
|
||||
*
|
||||
*/
|
||||
|
||||
void ignore_handler_s(const char *msg, void *ptr, errno_t error)
|
||||
{
|
||||
|
||||
sldebug_printf("IGNORE CONSTRAINT HANDLER: (%u) %s\n", error,
|
||||
(msg) ? msg : "Null message");
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(ignore_handler_s)
|
|
@ -0,0 +1,855 @@
|
|||
/*------------------------------------------------------------------
|
||||
* mem_primitives_lib.c - Unguarded Memory Copy Routines
|
||||
*
|
||||
* February 2005, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2005-2009 Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "mem_primitives_lib.h"
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wpragmas"
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
||||
/*
|
||||
* mem_primitives_lib.c provides unguarded memory routines
|
||||
* that are used by the safe_mem_library. These routines
|
||||
* may also be used by an application, but the application
|
||||
* is responsible for all parameter validation and alignment.
|
||||
*/
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_set - Sets memory to value
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_set(void *dest, uint32_t len, uint8_t value)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Sets len bytes starting at dest to the specified value
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest - pointer to memory that will be set to value
|
||||
*
|
||||
* len - number of bytes to be set
|
||||
*
|
||||
* value - byte value
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_set (void *dest, uint32_t len, uint8_t value)
|
||||
{
|
||||
uint8_t *dp;
|
||||
uint32_t count;
|
||||
uint32_t lcount;
|
||||
|
||||
uint32_t *lp;
|
||||
uint32_t value32;
|
||||
|
||||
count = len;
|
||||
|
||||
dp = dest;
|
||||
|
||||
value32 = value | (value << 8) | (value << 16) | (value << 24);
|
||||
|
||||
/*
|
||||
* First, do the few bytes to get uint32_t aligned.
|
||||
*/
|
||||
for (; count && ( (uintptr_t)dp & (sizeof(uint32_t)-1) ); count--) {
|
||||
*dp++ = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Then do the uint32_ts, unrolled the loop for performance
|
||||
*/
|
||||
lp = (uint32_t *)dp;
|
||||
lcount = count >> 2;
|
||||
|
||||
while (lcount != 0) {
|
||||
|
||||
switch (lcount) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32;
|
||||
*lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32;
|
||||
*lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32;
|
||||
*lp++ = value32; *lp++ = value32; *lp++ = value32; *lp++ = value32;
|
||||
lcount -= 16;
|
||||
break;
|
||||
|
||||
case 15: *lp++ = value32;
|
||||
case 14: *lp++ = value32;
|
||||
case 13: *lp++ = value32;
|
||||
case 12: *lp++ = value32;
|
||||
case 11: *lp++ = value32;
|
||||
case 10: *lp++ = value32;
|
||||
case 9: *lp++ = value32;
|
||||
case 8: *lp++ = value32;
|
||||
|
||||
case 7: *lp++ = value32;
|
||||
case 6: *lp++ = value32;
|
||||
case 5: *lp++ = value32;
|
||||
case 4: *lp++ = value32;
|
||||
case 3: *lp++ = value32;
|
||||
case 2: *lp++ = value32;
|
||||
case 1: *lp++ = value32;
|
||||
lcount = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
|
||||
dp = (uint8_t *)lp;
|
||||
|
||||
/*
|
||||
* compute the number of remaining bytes
|
||||
*/
|
||||
count &= (sizeof(uint32_t)-1);
|
||||
|
||||
/*
|
||||
* remaining bytes
|
||||
*/
|
||||
for (; count; dp++, count--) {
|
||||
*dp = value;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_set16 - Sets memory to value
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_set16(uint16_t *dp, uint32_t len, uint16_t value)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Sets len uint16_ts starting at dest to the specified value.
|
||||
* Pointers must meet system alignment requirements.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest - pointer to memory that will be set to value
|
||||
*
|
||||
* len - number of uint16_ts to be set
|
||||
*
|
||||
* value - uint16_t value
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_set16 (uint16_t *dp, uint32_t len, uint16_t value)
|
||||
{
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = value;
|
||||
case 14: *dp++ = value;
|
||||
case 13: *dp++ = value;
|
||||
case 12: *dp++ = value;
|
||||
case 11: *dp++ = value;
|
||||
case 10: *dp++ = value;
|
||||
case 9: *dp++ = value;
|
||||
case 8: *dp++ = value;
|
||||
|
||||
case 7: *dp++ = value;
|
||||
case 6: *dp++ = value;
|
||||
case 5: *dp++ = value;
|
||||
case 4: *dp++ = value;
|
||||
case 3: *dp++ = value;
|
||||
case 2: *dp++ = value;
|
||||
case 1: *dp++ = value;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_set32 - Sets memory to the uint32_t value
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_set32(uint32_t *dp, uint32_t len, uint32_t value)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Sets len uint32_ts starting at dest to the specified value
|
||||
* Pointers must meet system alignment requirements.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest - pointer to memory that will be set to value
|
||||
*
|
||||
* len - number of uint32_ts to be set
|
||||
*
|
||||
* value - uint32_t value
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_set32 (uint32_t *dp, uint32_t len, uint32_t value)
|
||||
{
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
*dp++ = value; *dp++ = value; *dp++ = value; *dp++ = value;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = value;
|
||||
case 14: *dp++ = value;
|
||||
case 13: *dp++ = value;
|
||||
case 12: *dp++ = value;
|
||||
case 11: *dp++ = value;
|
||||
case 10: *dp++ = value;
|
||||
case 9: *dp++ = value;
|
||||
case 8: *dp++ = value;
|
||||
|
||||
case 7: *dp++ = value;
|
||||
case 6: *dp++ = value;
|
||||
case 5: *dp++ = value;
|
||||
case 4: *dp++ = value;
|
||||
case 3: *dp++ = value;
|
||||
case 2: *dp++ = value;
|
||||
case 1: *dp++ = value;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_move - Move (handles overlap) memory
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_move(void *dest, const void *src, uint32_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Moves at most slen bytes from src to dest, up to dmax
|
||||
* bytes. Dest may overlap with src.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest - pointer to the memory that will be replaced by src.
|
||||
*
|
||||
* src - pointer to the memory that will be copied
|
||||
* to dest
|
||||
*
|
||||
* len - maximum number bytes of src that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_move (void *dest, const void *src, uint32_t len)
|
||||
{
|
||||
|
||||
#define wsize sizeof(uint32_t)
|
||||
#define wmask (wsize - 1)
|
||||
|
||||
uint8_t *dp = dest;
|
||||
const uint8_t *sp = src;
|
||||
|
||||
uint32_t tsp;
|
||||
|
||||
/*
|
||||
* Determine if we need to copy forward or backward (overlap)
|
||||
*/
|
||||
if ((uintptr_t)dp < (uintptr_t)sp) {
|
||||
/*
|
||||
* Copy forward.
|
||||
*/
|
||||
|
||||
/*
|
||||
* get a working copy of src for bit operations
|
||||
*/
|
||||
tsp = (uintptr_t)sp;
|
||||
|
||||
/*
|
||||
* Try to align both operands. This cannot be done
|
||||
* unless the low bits match.
|
||||
*/
|
||||
if ((tsp | (uintptr_t)dp) & wmask) {
|
||||
/*
|
||||
* determine how many bytes to copy to align operands
|
||||
*/
|
||||
if ((tsp ^ (uintptr_t)dp) & wmask || len < wsize) {
|
||||
tsp = len;
|
||||
|
||||
} else {
|
||||
tsp = wsize - (tsp & wmask);
|
||||
}
|
||||
|
||||
len -= tsp;
|
||||
|
||||
/*
|
||||
* make the alignment
|
||||
*/
|
||||
do {
|
||||
*dp++ = *sp++;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now copy, then mop up any trailing bytes.
|
||||
*/
|
||||
tsp = len / wsize;
|
||||
|
||||
if (tsp > 0) {
|
||||
|
||||
do {
|
||||
*(uint32_t *)dp = *(uint32_t *)sp;
|
||||
|
||||
sp += wsize;
|
||||
dp += wsize;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy over the remaining bytes and we're done
|
||||
*/
|
||||
tsp = len & wmask;
|
||||
|
||||
if (tsp > 0) {
|
||||
do {
|
||||
*dp++ = *sp++;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
* This section is used to copy backwards, to handle any
|
||||
* overlap. The alignment requires (tps&wmask) bytes to
|
||||
* align.
|
||||
*/
|
||||
|
||||
/*
|
||||
* go to end of the memory to copy
|
||||
*/
|
||||
sp += len;
|
||||
dp += len;
|
||||
|
||||
/*
|
||||
* get a working copy of src for bit operations
|
||||
*/
|
||||
tsp = (uintptr_t)sp;
|
||||
|
||||
/*
|
||||
* Try to align both operands.
|
||||
*/
|
||||
if ((tsp | (uintptr_t)dp) & wmask) {
|
||||
|
||||
if ((tsp ^ (uintptr_t)dp) & wmask || len <= wsize) {
|
||||
tsp = len;
|
||||
} else {
|
||||
tsp &= wmask;
|
||||
}
|
||||
|
||||
len -= tsp;
|
||||
|
||||
/*
|
||||
* make the alignment
|
||||
*/
|
||||
do {
|
||||
*--dp = *--sp;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now copy in uint32_t units, then mop up any trailing bytes.
|
||||
*/
|
||||
tsp = len / wsize;
|
||||
|
||||
if (tsp > 0) {
|
||||
do {
|
||||
sp -= wsize;
|
||||
dp -= wsize;
|
||||
|
||||
*(uint32_t *)dp = *(uint32_t *)sp;
|
||||
} while (--tsp);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy over the remaining bytes and we're done
|
||||
*/
|
||||
tsp = len & wmask;
|
||||
if (tsp > 0) {
|
||||
tsp = len & wmask;
|
||||
do {
|
||||
*--dp = *--sp;
|
||||
} while (--tsp);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_move8 - Move (handles overlap) memory
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_move8(void *dest, const void *src, uint32_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Moves at most len uint8_ts from sp to dp.
|
||||
* The destination may overlap with source.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dp - pointer to the memory that will be replaced by sp.
|
||||
*
|
||||
* sp - pointer to the memory that will be copied
|
||||
* to dp
|
||||
*
|
||||
* len - maximum number uint8_t of sp that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dp - pointer to the memory that will be replaced by sp.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_move8 (uint8_t *dp, const uint8_t *sp, uint32_t len)
|
||||
{
|
||||
|
||||
/*
|
||||
* Determine if we need to copy forward or backward (overlap)
|
||||
*/
|
||||
if (dp < sp) {
|
||||
/*
|
||||
* Copy forward.
|
||||
*/
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = *sp++;
|
||||
case 14: *dp++ = *sp++;
|
||||
case 13: *dp++ = *sp++;
|
||||
case 12: *dp++ = *sp++;
|
||||
case 11: *dp++ = *sp++;
|
||||
case 10: *dp++ = *sp++;
|
||||
case 9: *dp++ = *sp++;
|
||||
case 8: *dp++ = *sp++;
|
||||
|
||||
case 7: *dp++ = *sp++;
|
||||
case 6: *dp++ = *sp++;
|
||||
case 5: *dp++ = *sp++;
|
||||
case 4: *dp++ = *sp++;
|
||||
case 3: *dp++ = *sp++;
|
||||
case 2: *dp++ = *sp++;
|
||||
case 1: *dp++ = *sp++;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
} else {
|
||||
/*
|
||||
* This section is used to copy backwards, to handle any
|
||||
* overlap. The alignment requires (tps&wmask) bytes to
|
||||
* align.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* go to end of the memory to copy
|
||||
*/
|
||||
sp += len;
|
||||
dp += len;
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *--dp = *--sp;
|
||||
case 14: *--dp = *--sp;
|
||||
case 13: *--dp = *--sp;
|
||||
case 12: *--dp = *--sp;
|
||||
case 11: *--dp = *--sp;
|
||||
case 10: *--dp = *--sp;
|
||||
case 9: *--dp = *--sp;
|
||||
case 8: *--dp = *--sp;
|
||||
|
||||
case 7: *--dp = *--sp;
|
||||
case 6: *--dp = *--sp;
|
||||
case 5: *--dp = *--sp;
|
||||
case 4: *--dp = *--sp;
|
||||
case 3: *--dp = *--sp;
|
||||
case 2: *--dp = *--sp;
|
||||
case 1: *--dp = *--sp;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_move16 - Move (handles overlap) memory
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_move16(void *dest, const void *src, uint32_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Moves at most len uint16_ts from sp to dp.
|
||||
* The destination may overlap with source.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dp - pointer to the memory that will be replaced by sp.
|
||||
*
|
||||
* sp - pointer to the memory that will be copied
|
||||
* to dp
|
||||
*
|
||||
* len - maximum number uint16_t of sp that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dp - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_move16 (uint16_t *dp, const uint16_t *sp, uint32_t len)
|
||||
{
|
||||
|
||||
/*
|
||||
* Determine if we need to copy forward or backward (overlap)
|
||||
*/
|
||||
if (dp < sp) {
|
||||
/*
|
||||
* Copy forward.
|
||||
*/
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = *sp++;
|
||||
case 14: *dp++ = *sp++;
|
||||
case 13: *dp++ = *sp++;
|
||||
case 12: *dp++ = *sp++;
|
||||
case 11: *dp++ = *sp++;
|
||||
case 10: *dp++ = *sp++;
|
||||
case 9: *dp++ = *sp++;
|
||||
case 8: *dp++ = *sp++;
|
||||
|
||||
case 7: *dp++ = *sp++;
|
||||
case 6: *dp++ = *sp++;
|
||||
case 5: *dp++ = *sp++;
|
||||
case 4: *dp++ = *sp++;
|
||||
case 3: *dp++ = *sp++;
|
||||
case 2: *dp++ = *sp++;
|
||||
case 1: *dp++ = *sp++;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
} else {
|
||||
/*
|
||||
* This section is used to copy backwards, to handle any
|
||||
* overlap. The alignment requires (tps&wmask) bytes to
|
||||
* align.
|
||||
*/
|
||||
|
||||
/*
|
||||
* go to end of the memory to copy
|
||||
*/
|
||||
sp += len;
|
||||
dp += len;
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *--dp = *--sp;
|
||||
case 14: *--dp = *--sp;
|
||||
case 13: *--dp = *--sp;
|
||||
case 12: *--dp = *--sp;
|
||||
case 11: *--dp = *--sp;
|
||||
case 10: *--dp = *--sp;
|
||||
case 9: *--dp = *--sp;
|
||||
case 8: *--dp = *--sp;
|
||||
|
||||
case 7: *--dp = *--sp;
|
||||
case 6: *--dp = *--sp;
|
||||
case 5: *--dp = *--sp;
|
||||
case 4: *--dp = *--sp;
|
||||
case 3: *--dp = *--sp;
|
||||
case 2: *--dp = *--sp;
|
||||
case 1: *--dp = *--sp;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* mem_prim_move32 - Move (handles overlap) memory
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "mem_primitives_lib.h"
|
||||
* void
|
||||
* mem_prim_move32(void *dest, const void *src, uint32_t len)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Moves at most len uint32_ts from sp to dp.
|
||||
* The destination may overlap with source.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dp - pointer to the memory that will be replaced by sp.
|
||||
*
|
||||
* sp - pointer to the memory that will be copied
|
||||
* to dp
|
||||
*
|
||||
* len - maximum number uint32_t of sp that can be copied
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dp - is updated
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
mem_prim_move32 (uint32_t *dp, const uint32_t *sp, uint32_t len)
|
||||
{
|
||||
|
||||
/*
|
||||
* Determine if we need to copy forward or backward (overlap)
|
||||
*/
|
||||
if (dp < sp) {
|
||||
/*
|
||||
* Copy forward.
|
||||
*/
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *dp++ = *sp++;
|
||||
case 14: *dp++ = *sp++;
|
||||
case 13: *dp++ = *sp++;
|
||||
case 12: *dp++ = *sp++;
|
||||
case 11: *dp++ = *sp++;
|
||||
case 10: *dp++ = *sp++;
|
||||
case 9: *dp++ = *sp++;
|
||||
case 8: *dp++ = *sp++;
|
||||
|
||||
case 7: *dp++ = *sp++;
|
||||
case 6: *dp++ = *sp++;
|
||||
case 5: *dp++ = *sp++;
|
||||
case 4: *dp++ = *sp++;
|
||||
case 3: *dp++ = *sp++;
|
||||
case 2: *dp++ = *sp++;
|
||||
case 1: *dp++ = *sp++;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
|
||||
} else {
|
||||
/*
|
||||
* This section is used to copy backwards, to handle any
|
||||
* overlap.
|
||||
*/
|
||||
|
||||
/*
|
||||
* go to end of the memory to copy
|
||||
*/
|
||||
sp += len;
|
||||
dp += len;
|
||||
|
||||
while (len != 0) {
|
||||
|
||||
switch (len) {
|
||||
/*
|
||||
* Here we do blocks of 8. Once the remaining count
|
||||
* drops below 8, take the fast track to finish up.
|
||||
*/
|
||||
default:
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
*--dp = *--sp; *--dp = *--sp; *--dp = *--sp; *--dp = *--sp;
|
||||
len -= 16;
|
||||
break;
|
||||
|
||||
case 15: *--dp = *--sp;
|
||||
case 14: *--dp = *--sp;
|
||||
case 13: *--dp = *--sp;
|
||||
case 12: *--dp = *--sp;
|
||||
case 11: *--dp = *--sp;
|
||||
case 10: *--dp = *--sp;
|
||||
case 9: *--dp = *--sp;
|
||||
case 8: *--dp = *--sp;
|
||||
|
||||
case 7: *--dp = *--sp;
|
||||
case 6: *--dp = *--sp;
|
||||
case 5: *--dp = *--sp;
|
||||
case 4: *--dp = *--sp;
|
||||
case 3: *--dp = *--sp;
|
||||
case 2: *--dp = *--sp;
|
||||
case 1: *--dp = *--sp;
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
} /* end while */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*------------------------------------------------------------------
|
||||
* mem_primitives_lib.h - Unguarded Memory Copy Routines
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 by Cisco Systems, Inc
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __MEM_PRIMITIVES_LIB_H__
|
||||
#define __MEM_PRIMITIVES_LIB_H__
|
||||
|
||||
#include "safeclib_private.h"
|
||||
|
||||
/*
|
||||
* These are prototypes for _unguarded_ memory routines. The caller must
|
||||
* validate all parameters prior to invocation. Useful for diagnostics
|
||||
* and system initialization processing.
|
||||
*/
|
||||
|
||||
/* moves (handles overlap) memory */
|
||||
extern void
|
||||
mem_prim_move(void *dest, const void *src, uint32_t length);
|
||||
|
||||
|
||||
/* uint8_t moves (handles overlap) memory */
|
||||
extern void
|
||||
mem_prim_move8(uint8_t *dest, const uint8_t *src, uint32_t length);
|
||||
|
||||
/* uint16_t moves (handles overlap) memory */
|
||||
extern void
|
||||
mem_prim_move16(uint16_t *dest, const uint16_t *src, uint32_t length);
|
||||
|
||||
/* uint32_t moves (handles overlap) memory */
|
||||
extern void
|
||||
mem_prim_move32(uint32_t *dest, const uint32_t *src, uint32_t length);
|
||||
|
||||
|
||||
/* set bytes */
|
||||
extern void
|
||||
mem_prim_set(void *dest, uint32_t dmax, uint8_t value);
|
||||
|
||||
/* set uint16_ts */
|
||||
extern void
|
||||
mem_prim_set16(uint16_t *dest, uint32_t dmax, uint16_t value);
|
||||
|
||||
/* set uint32_ts */
|
||||
extern void
|
||||
mem_prim_set32(uint32_t *dest, uint32_t dmax, uint32_t value);
|
||||
|
||||
|
||||
#endif /* __MEM_PRIMITIVES_LIB_H__ */
|
|
@ -0,0 +1,163 @@
|
|||
/*------------------------------------------------------------------
|
||||
* memcpy_s
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "safeclib_private.h"
|
||||
#include "safe_mem_constraint.h"
|
||||
#include "mem_primitives_lib.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* memcpy_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* errno_t
|
||||
* memcpy_s(void *dest, rsize_t dmax, const void *src, rsize_t smax)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This function copies at most smax bytes from src to dest, up to
|
||||
* dmax. The size values are unsigned values.
|
||||
*
|
||||
* AR: Dave - verify ISO spec requires unsigned
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* dest pointer to memory that will be replaced by src.
|
||||
*
|
||||
* dmax maximum length of the resulting dest
|
||||
*
|
||||
* src pointer to the memory that will be copied to dest
|
||||
*
|
||||
* smax maximum number bytes of src to copy
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* dest is updated
|
||||
*
|
||||
* RUNTIME CONSTRAINTS
|
||||
* Neither dest nor src shall be a null pointer.
|
||||
* Neither dmax nor smax shall be zero.
|
||||
* dmax shall not be greater than RSIZE_MAX_MEM.
|
||||
* smax shall not be greater than dmax.
|
||||
* Copying shall not take place between regions that overlap.
|
||||
* If there is a runtime-constraint violation, the memcpy_s function
|
||||
* stores zeros in the first dmax bytes of the region pointed to
|
||||
* by dest if dest is not a null pointer and smax is valid.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* EOK successful operation
|
||||
* ESNULLP NULL pointer
|
||||
* ESZEROL zero length
|
||||
* ESLEMAX length exceeds max limit
|
||||
* ESOVRLP source memory overlaps destination
|
||||
*
|
||||
* ALSO SEE
|
||||
* memcpy16_s(), memcpy32_s(), memmove_s(), memmove16_s(),
|
||||
* memmove32_s()
|
||||
*
|
||||
*/
|
||||
errno_t
|
||||
memcpy_s (void *dest, rsize_t dmax, const void *src, rsize_t smax)
|
||||
{
|
||||
uint8_t *dp;
|
||||
const uint8_t *sp;
|
||||
|
||||
dp = dest;
|
||||
sp = src;
|
||||
|
||||
if (dp == NULL) {
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: dest is NULL",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
if (dmax == 0) {
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: dmax is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (dmax > RSIZE_MAX_MEM) {
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: dmax exceeds max",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
// AR: This is not a requirement according to the ISO spec - Change?
|
||||
// AR: documentation needed on use of the error handlers -
|
||||
// AR: default err handler should output to stderr on DEBUG
|
||||
// AR: update docs to define return RCNEGATE of the error number
|
||||
if (smax == 0) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: smax is 0",
|
||||
NULL, ESZEROL);
|
||||
return RCNEGATE(ESZEROL);
|
||||
}
|
||||
|
||||
if (smax > dmax) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: smax exceeds dmax",
|
||||
NULL, ESLEMAX);
|
||||
return RCNEGATE(ESLEMAX);
|
||||
}
|
||||
|
||||
if (sp == NULL) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: src is NULL",
|
||||
NULL, ESNULLP);
|
||||
return RCNEGATE(ESNULLP);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* overlap is undefined behavior, do not allow
|
||||
*/
|
||||
if( ((dp > sp) && (dp < (sp+smax))) ||
|
||||
((sp > dp) && (sp < (dp+dmax))) ) {
|
||||
mem_prim_set(dp, dmax, 0);
|
||||
invoke_safe_mem_constraint_handler("memcpy_s: overlap undefined",
|
||||
NULL, ESOVRLP);
|
||||
return RCNEGATE(ESOVRLP);
|
||||
}
|
||||
|
||||
/*
|
||||
* now perform the copy
|
||||
*/
|
||||
mem_prim_move(dp, sp, smax);
|
||||
|
||||
return RCNEGATE(EOK);
|
||||
}
|
||||
EXPORT_SYMBOL(memcpy_s)
|
|
@ -22,16 +22,20 @@
|
|||
|
||||
#include "columnar/columnar_tableam.h"
|
||||
|
||||
void _PG_init(void);
|
||||
void _PG_fini(void);
|
||||
|
||||
//columnar_init
|
||||
void
|
||||
columnar_init(void)
|
||||
_PG_init(void)
|
||||
{
|
||||
columnar_init_gucs();
|
||||
columnar_tableam_init();
|
||||
}
|
||||
|
||||
|
||||
//columnar_fini
|
||||
void
|
||||
columnar_fini(void)
|
||||
_PG_fini(void)
|
||||
{
|
||||
columnar_tableam_finish();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_mem_constraint.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2008-2012 Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "safeclib_private.h"
|
||||
#include "safe_mem_constraint.h"
|
||||
#include "safe_mem_lib.h"
|
||||
|
||||
|
||||
static constraint_handler_t mem_handler = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* set_mem_constraint_handler_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_lib.h"
|
||||
* constraint_handler_t
|
||||
* set_mem_constraint_handler_straint_handler_t handler)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The set_mem_constraint_handler_s function sets the runtime-constraint
|
||||
* handler to be handler. The runtime-constraint handler is the function to
|
||||
* be called when a library function detects a runtime-constraint
|
||||
* order:
|
||||
* 1. A pointer to a character string describing the
|
||||
* runtime-constraint violation.
|
||||
* 2. A null pointer or a pointer to an implementation defined
|
||||
* object.
|
||||
* 3. If the function calling the handler has a return type declared
|
||||
* as errno_t, the return value of the function is passed.
|
||||
* Otherwise, a positive value of type errno_t is passed.
|
||||
* The implementation has a default constraint handler that is used if no
|
||||
* calls to the set_constraint_handler_s function have been made. The
|
||||
* behavior of the default handler is implementation-defined, and it may
|
||||
* cause the program to exit or abort. If the handler argument to
|
||||
* set_constraint_handler_s is a null pointer, the implementation default
|
||||
* handler becomes the current constraint handler.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* *msg Pointer to the message describing the error
|
||||
*
|
||||
* *ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
* ALSO SEE
|
||||
* set_str_constraint_handler_s()
|
||||
*/
|
||||
constraint_handler_t
|
||||
set_mem_constraint_handler_s (constraint_handler_t handler)
|
||||
{
|
||||
constraint_handler_t prev_handler = mem_handler;
|
||||
if (NULL == handler) {
|
||||
mem_handler = sl_default_handler;
|
||||
} else {
|
||||
mem_handler = handler;
|
||||
}
|
||||
return prev_handler;
|
||||
}
|
||||
EXPORT_SYMBOL(set_mem_constraint_handler_s)
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* invoke_safe_mem_constraint_handler
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_mem_constraint.h"
|
||||
* void
|
||||
* invoke_safe_mem_constraint_handler(const char *msg,
|
||||
* void *ptr,
|
||||
* errno_t error)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Invokes the currently set constraint handler or the default.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* *msg Pointer to the message describing the error
|
||||
*
|
||||
* *ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
invoke_safe_mem_constraint_handler (const char *msg,
|
||||
void *ptr,
|
||||
errno_t error)
|
||||
{
|
||||
if (NULL != mem_handler) {
|
||||
mem_handler(msg, ptr, error);
|
||||
} else {
|
||||
sl_default_handler(msg, ptr, error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_mem_constraint.h
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008, 2009 by Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_MEM_CONSTRAINT_H__
|
||||
#define __SAFE_MEM_CONSTRAINT_H__
|
||||
|
||||
#include "safeclib_private.h"
|
||||
|
||||
/*
|
||||
* Function used by the libraries to invoke the registered
|
||||
* runtime-constraint handler. Always needed.
|
||||
*/
|
||||
extern void invoke_safe_mem_constraint_handler(
|
||||
const char *msg,
|
||||
void *ptr,
|
||||
errno_t error);
|
||||
|
||||
#endif /* __SAFE_MEM_CONSTRAINT_H__ */
|
|
@ -0,0 +1,146 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_str_constraint.c
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2008, 2009, 2012 Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "safeclib_private.h"
|
||||
#include "safe_str_constraint.h"
|
||||
#include "safe_str_lib.h"
|
||||
|
||||
|
||||
static constraint_handler_t str_handler = NULL;
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* set_str_constraint_handler_s
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_lib.h"
|
||||
* constraint_handler_t
|
||||
* set_str_constraint_handler_s(constraint_handler_t handler)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The set_str_constraint_handler_s function sets the runtime-constraint
|
||||
* handler to be handler. The runtime-constraint handler is the function to
|
||||
* be called when a library function detects a runtime-constraint
|
||||
* violation. Only the most recent handler registered with
|
||||
* set_str_constraint_handler_s is called when a runtime-constraint
|
||||
* violation occurs.
|
||||
* When the handler is called, it is passed the following arguments in
|
||||
* the following order:
|
||||
* 1. A pointer to a character string describing the
|
||||
* runtime-constraint violation.
|
||||
* 2. A null pointer or a pointer to an implementation defined
|
||||
* object.
|
||||
* 3. If the function calling the handler has a return type declared
|
||||
* as errno_t, the return value of the function is passed.
|
||||
* Otherwise, a positive value of type errno_t is passed.
|
||||
* The implementation has a default constraint handler that is used if no
|
||||
* calls to the set_constraint_handler_s function have been made. The
|
||||
* behavior of the default handler is implementation-defined, and it may
|
||||
* cause the program to exit or abort. If the handler argument to
|
||||
* set_constraint_handler_s is a null pointer, the implementation default
|
||||
* handler becomes the current constraint handler.
|
||||
*
|
||||
* SPECIFIED IN
|
||||
* ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
|
||||
* and system software interfaces, Extensions to the C Library,
|
||||
* Part I: Bounds-checking interfaces
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* *msg Pointer to the message describing the error
|
||||
*
|
||||
* *ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
* ALSO SEE
|
||||
* set_str_constraint_handler_s()
|
||||
*/
|
||||
constraint_handler_t
|
||||
set_str_constraint_handler_s (constraint_handler_t handler)
|
||||
{
|
||||
constraint_handler_t prev_handler = str_handler;
|
||||
if (NULL == handler) {
|
||||
str_handler = sl_default_handler;
|
||||
} else {
|
||||
str_handler = handler;
|
||||
}
|
||||
return prev_handler;
|
||||
}
|
||||
EXPORT_SYMBOL(set_str_constraint_handler_s)
|
||||
|
||||
|
||||
/**
|
||||
* NAME
|
||||
* invoke_safe_str_constraint_handler
|
||||
*
|
||||
* SYNOPSIS
|
||||
* #include "safe_str_constraint.h"
|
||||
* void
|
||||
* invoke_safe_str_constraint_handler (const char *msg,
|
||||
* void *ptr,
|
||||
* errno_t error)
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Invokes the currently set constraint handler or the default.
|
||||
*
|
||||
* INPUT PARAMETERS
|
||||
* *msg Pointer to the message describing the error
|
||||
*
|
||||
* *ptr Pointer to aassociated data. Can be NULL.
|
||||
*
|
||||
* error The error code encountered.
|
||||
*
|
||||
* OUTPUT PARAMETERS
|
||||
* none
|
||||
*
|
||||
* RETURN VALUE
|
||||
* none
|
||||
*
|
||||
*/
|
||||
void
|
||||
invoke_safe_str_constraint_handler (const char *msg,
|
||||
void *ptr,
|
||||
errno_t error)
|
||||
{
|
||||
if (NULL != str_handler) {
|
||||
str_handler(msg, ptr, error);
|
||||
} else {
|
||||
sl_default_handler(msg, ptr, error);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safe_str_constraint.h
|
||||
*
|
||||
* October 2008, Bo Berry
|
||||
*
|
||||
* Copyright (c) 2008-2011 Cisco Systems
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFE_STR_CONSTRAINT_H__
|
||||
#define __SAFE_STR_CONSTRAINT_H__
|
||||
|
||||
#include "safeclib_private.h"
|
||||
|
||||
/*
|
||||
* Function used by the libraries to invoke the registered
|
||||
* runtime-constraint handler. Always needed.
|
||||
*/
|
||||
extern void invoke_safe_str_constraint_handler(
|
||||
const char *msg,
|
||||
void *ptr,
|
||||
errno_t error);
|
||||
|
||||
|
||||
/*
|
||||
* Safe C Lib internal string routine to consolidate error handling
|
||||
*/
|
||||
static inline void handle_error(char *orig_dest, rsize_t orig_dmax,
|
||||
char *err_msg, errno_t err_code)
|
||||
{
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null string to eliminate partial copy */
|
||||
while (orig_dmax) { *orig_dest = '\0'; orig_dmax--; orig_dest++; }
|
||||
#else
|
||||
*orig_dest = '\0';
|
||||
#endif
|
||||
|
||||
invoke_safe_str_constraint_handler(err_msg, NULL, err_code);
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void handle_wc_error(wchar_t *orig_dest, rsize_t orig_dmax,
|
||||
char *err_msg, errno_t err_code)
|
||||
{
|
||||
#ifdef SAFECLIB_STR_NULL_SLACK
|
||||
/* null string to eliminate partial copy */
|
||||
while (orig_dmax) { *orig_dest = L'\0'; orig_dmax--; orig_dest++; }
|
||||
#else
|
||||
*orig_dest = L'\0';
|
||||
#endif
|
||||
|
||||
invoke_safe_str_constraint_handler(err_msg, NULL, err_code);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* __SAFE_STR_CONSTRAINT_H__ */
|
|
@ -0,0 +1,94 @@
|
|||
/*------------------------------------------------------------------
|
||||
* safeclib_private.h - Internal library references
|
||||
*
|
||||
* 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
|
||||
*
|
||||
* Copyright (c) 2012, 2013 by Cisco Systems, Inc
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef __SAFECLIB_PRIVATE_H__
|
||||
#define __SAFECLIB_PRIVATE_H__
|
||||
|
||||
#include "citus_config.h"
|
||||
#ifdef __KERNEL__
|
||||
/* linux kernel environment */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
#define RCNEGATE(x) ( -(x) )
|
||||
|
||||
#define slprintf(...) printk(KERN_EMERG __VA_ARGS__)
|
||||
#define slabort()
|
||||
#ifdef DEBUG
|
||||
#define sldebug_printf(...) printk(KERN_DEBUG __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#else /* !__KERNEL__ */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef STDC_HEADERS
|
||||
# include <ctype.h>
|
||||
# include <stdlib.h>
|
||||
# include <stddef.h>
|
||||
#else
|
||||
# ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
#define EXPORT_SYMBOL(sym)
|
||||
#define RCNEGATE(x) (x)
|
||||
|
||||
#define slprintf(...) fprintf(stderr, __VA_ARGS__)
|
||||
#define slabort() abort()
|
||||
#ifdef DEBUG
|
||||
#define sldebug_printf(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#ifndef sldebug_printf
|
||||
#define sldebug_printf(...)
|
||||
#endif
|
||||
|
||||
#include "safe_lib.h"
|
||||
|
||||
#endif /* __SAFECLIB_PRIVATE_H__ */
|
|
@ -0,0 +1,332 @@
|
|||
-- columnar--9.5-1--10.0-1.sql
|
||||
|
||||
CREATE SCHEMA columnar;
|
||||
SET search_path TO columnar;
|
||||
|
||||
|
||||
CREATE SEQUENCE storageid_seq MINVALUE 10000000000 NO CYCLE;
|
||||
|
||||
CREATE TABLE options (
|
||||
regclass regclass NOT NULL PRIMARY KEY,
|
||||
chunk_group_row_limit int NOT NULL,
|
||||
stripe_row_limit int NOT NULL,
|
||||
compression_level int NOT NULL,
|
||||
compression name NOT NULL
|
||||
) WITH (user_catalog_table = true);
|
||||
|
||||
COMMENT ON TABLE options IS 'columnar table specific options, maintained by alter_columnar_table_set';
|
||||
|
||||
CREATE TABLE stripe (
|
||||
storage_id bigint NOT NULL,
|
||||
stripe_num bigint NOT NULL,
|
||||
file_offset bigint NOT NULL,
|
||||
data_length bigint NOT NULL,
|
||||
column_count int NOT NULL,
|
||||
chunk_row_count int NOT NULL,
|
||||
row_count bigint NOT NULL,
|
||||
chunk_group_count int NOT NULL,
|
||||
PRIMARY KEY (storage_id, stripe_num)
|
||||
) WITH (user_catalog_table = true);
|
||||
|
||||
COMMENT ON TABLE stripe IS 'Columnar per stripe metadata';
|
||||
|
||||
CREATE TABLE chunk_group (
|
||||
storage_id bigint NOT NULL,
|
||||
stripe_num bigint NOT NULL,
|
||||
chunk_group_num int NOT NULL,
|
||||
row_count bigint NOT NULL,
|
||||
PRIMARY KEY (storage_id, stripe_num, chunk_group_num),
|
||||
FOREIGN KEY (storage_id, stripe_num) REFERENCES stripe(storage_id, stripe_num) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
COMMENT ON TABLE chunk_group IS 'Columnar chunk group metadata';
|
||||
|
||||
CREATE TABLE chunk (
|
||||
storage_id bigint NOT NULL,
|
||||
stripe_num bigint NOT NULL,
|
||||
attr_num int NOT NULL,
|
||||
chunk_group_num int NOT NULL,
|
||||
minimum_value bytea,
|
||||
maximum_value bytea,
|
||||
value_stream_offset bigint NOT NULL,
|
||||
value_stream_length bigint NOT NULL,
|
||||
exists_stream_offset bigint NOT NULL,
|
||||
exists_stream_length bigint NOT NULL,
|
||||
value_compression_type int NOT NULL,
|
||||
value_compression_level int NOT NULL,
|
||||
value_decompressed_length bigint NOT NULL,
|
||||
value_count bigint NOT NULL,
|
||||
PRIMARY KEY (storage_id, stripe_num, attr_num, chunk_group_num),
|
||||
FOREIGN KEY (storage_id, stripe_num, chunk_group_num) REFERENCES chunk_group(storage_id, stripe_num, chunk_group_num) ON DELETE CASCADE
|
||||
) WITH (user_catalog_table = true);
|
||||
|
||||
COMMENT ON TABLE chunk IS 'Columnar per chunk metadata';
|
||||
|
||||
DO $proc$
|
||||
BEGIN
|
||||
|
||||
-- from version 12 and up we have support for tableam's if installed on pg11 we can't
|
||||
-- create the objects here. Instead we rely on citus_finish_pg_upgrade to be called by the
|
||||
-- user instead to add the missing objects
|
||||
IF substring(current_Setting('server_version'), '\d+')::int >= 12 THEN
|
||||
EXECUTE $$
|
||||
--#include "udfs/columnar_handler/10.0-1.sql"
|
||||
CREATE OR REPLACE FUNCTION columnar.columnar_handler(internal)
|
||||
RETURNS table_am_handler
|
||||
LANGUAGE C
|
||||
AS 'MODULE_PATHNAME', 'columnar_handler';
|
||||
COMMENT ON FUNCTION columnar.columnar_handler(internal)
|
||||
IS 'internal function returning the handler for columnar tables';
|
||||
|
||||
-- postgres 11.8 does not support the syntax for table am, also it is seemingly trying
|
||||
-- to parse the upgrade file and erroring on unknown syntax.
|
||||
-- normally this section would not execute on postgres 11 anyway. To trick it to pass on
|
||||
-- 11.8 we wrap the statement in a plpgsql block together with an EXECUTE. This is valid
|
||||
-- syntax on 11.8 and will execute correctly in 12
|
||||
DO $create_table_am$
|
||||
BEGIN
|
||||
EXECUTE 'CREATE ACCESS METHOD columnar TYPE TABLE HANDLER columnar.columnar_handler';
|
||||
END $create_table_am$;
|
||||
|
||||
--#include "udfs/alter_columnar_table_set/10.0-1.sql"
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.alter_columnar_table_set(
|
||||
table_name regclass,
|
||||
chunk_group_row_limit int DEFAULT NULL,
|
||||
stripe_row_limit int DEFAULT NULL,
|
||||
compression name DEFAULT null,
|
||||
compression_level int DEFAULT NULL)
|
||||
RETURNS void
|
||||
LANGUAGE C
|
||||
AS 'MODULE_PATHNAME', 'alter_columnar_table_set';
|
||||
|
||||
COMMENT ON FUNCTION pg_catalog.alter_columnar_table_set(
|
||||
table_name regclass,
|
||||
chunk_group_row_limit int,
|
||||
stripe_row_limit int,
|
||||
compression name,
|
||||
compression_level int)
|
||||
IS 'set one or more options on a columnar table, when set to NULL no change is made';
|
||||
|
||||
|
||||
--#include "udfs/alter_columnar_table_reset/10.0-1.sql"
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.alter_columnar_table_reset(
|
||||
table_name regclass,
|
||||
chunk_group_row_limit bool DEFAULT false,
|
||||
stripe_row_limit bool DEFAULT false,
|
||||
compression bool DEFAULT false,
|
||||
compression_level bool DEFAULT false)
|
||||
RETURNS void
|
||||
LANGUAGE C
|
||||
AS 'MODULE_PATHNAME', 'alter_columnar_table_reset';
|
||||
|
||||
COMMENT ON FUNCTION pg_catalog.alter_columnar_table_reset(
|
||||
table_name regclass,
|
||||
chunk_group_row_limit bool,
|
||||
stripe_row_limit bool,
|
||||
compression bool,
|
||||
compression_level bool)
|
||||
IS 'reset on or more options on a columnar table to the system defaults';
|
||||
|
||||
$$;
|
||||
END IF;
|
||||
END$proc$;
|
||||
|
||||
-- dropped in 10.0.3#include "udfs/columnar_ensure_objects_exist/10.0-1.sql"
|
||||
|
||||
-- citus_internal.columnar_ensure_objects_exist is an internal helper function to create
|
||||
-- missing objects, anything related to the table access methods.
|
||||
-- Since the API for table access methods is only available in PG12 we can't create these
|
||||
-- objects when Citus is installed in PG11. Once citus is installed on PG11 the user can
|
||||
-- upgrade their database to PG12. Now they require the table access method objects that
|
||||
-- we couldn't create before.
|
||||
-- This internal function is called from `citus_finish_pg_upgrade` which the user is
|
||||
-- required to call after a PG major upgrade.
|
||||
CREATE OR REPLACE FUNCTION columnar_ensure_objects_exist()
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
SET search_path = pg_catalog
|
||||
AS $ceoe$
|
||||
BEGIN
|
||||
|
||||
-- when postgres is version 12 or above we need to create the tableam. If the tableam
|
||||
-- exist we assume all objects have been created.
|
||||
--IF substring(current_Setting('server_version'), '\d+')::int >= 12 THEN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_am WHERE amname = 'columnar') THEN
|
||||
|
||||
--#include "../columnar_handler/10.0-1.sql"
|
||||
|
||||
--#include "../alter_columnar_table_set/10.0-1.sql"
|
||||
|
||||
--#include "../alter_columnar_table_reset/10.0-1.sql"
|
||||
|
||||
-- Need change extension name to columnar ???
|
||||
-- add the missing objects to the extension
|
||||
ALTER EXTENSION citus ADD FUNCTION columnar.columnar_handler(internal);
|
||||
ALTER EXTENSION citus ADD ACCESS METHOD columnar;
|
||||
ALTER EXTENSION citus ADD FUNCTION pg_catalog.alter_columnar_table_set(
|
||||
table_name regclass,
|
||||
chunk_group_row_limit int,
|
||||
stripe_row_limit int,
|
||||
compression name,
|
||||
compression_level int);
|
||||
ALTER EXTENSION citus ADD FUNCTION pg_catalog.alter_columnar_table_reset(
|
||||
table_name regclass,
|
||||
chunk_group_row_limit bool,
|
||||
stripe_row_limit bool,
|
||||
compression bool,
|
||||
compression_level bool);
|
||||
|
||||
END IF;
|
||||
END IF;
|
||||
END;
|
||||
$ceoe$;
|
||||
|
||||
COMMENT ON FUNCTION columnar_ensure_objects_exist()
|
||||
IS 'internal function to be called by pg_catalog.citus_finish_pg_upgrade responsible for creating the columnar objects';
|
||||
|
||||
|
||||
RESET search_path;
|
||||
|
||||
-- columnar--10.0.-1 --10.0.2
|
||||
GRANT USAGE ON SCHEMA columnar TO PUBLIC;
|
||||
GRANT SELECT ON ALL tables IN SCHEMA columnar TO PUBLIC ;
|
||||
|
||||
-- columnar--10.0-3--10.1-1.sql
|
||||
|
||||
-- Drop foreign keys between columnar metadata tables.
|
||||
-- Postgres assigns different names to those foreign keys in PG11, so act accordingly.
|
||||
DO $proc$
|
||||
BEGIN
|
||||
IF substring(current_Setting('server_version'), '\d+')::int >= 12 THEN
|
||||
EXECUTE $$
|
||||
ALTER TABLE columnar.chunk DROP CONSTRAINT chunk_storage_id_stripe_num_chunk_group_num_fkey;
|
||||
ALTER TABLE columnar.chunk_group DROP CONSTRAINT chunk_group_storage_id_stripe_num_fkey;
|
||||
$$;
|
||||
ELSE
|
||||
EXECUTE $$
|
||||
ALTER TABLE columnar.chunk DROP CONSTRAINT chunk_storage_id_fkey;
|
||||
ALTER TABLE columnar.chunk_group DROP CONSTRAINT chunk_group_storage_id_fkey;
|
||||
$$;
|
||||
END IF;
|
||||
END$proc$;
|
||||
|
||||
--10.1-1 -- 10.2-1
|
||||
|
||||
-- columnar--10.1-1--10.2-1.sql
|
||||
|
||||
-- For a proper mapping between tid & (stripe, row_num), add a new column to
|
||||
-- columnar.stripe and define a BTREE index on this column.
|
||||
-- Also include storage_id column for per-relation scans.
|
||||
ALTER TABLE columnar.stripe ADD COLUMN first_row_number bigint;
|
||||
CREATE INDEX stripe_first_row_number_idx ON columnar.stripe USING BTREE(storage_id, first_row_number);
|
||||
|
||||
-- Populate first_row_number column of columnar.stripe table.
|
||||
--
|
||||
-- For simplicity, we calculate MAX(row_count) value across all the stripes
|
||||
-- of all the columanar tables and then use it to populate first_row_number
|
||||
-- column. This would introduce some gaps however we are okay with that since
|
||||
-- it's already the case with regular INSERT/COPY's.
|
||||
DO $$
|
||||
DECLARE
|
||||
max_row_count bigint;
|
||||
-- this should be equal to columnar_storage.h/COLUMNAR_FIRST_ROW_NUMBER
|
||||
COLUMNAR_FIRST_ROW_NUMBER constant bigint := 1;
|
||||
BEGIN
|
||||
SELECT MAX(row_count) INTO max_row_count FROM columnar.stripe;
|
||||
UPDATE columnar.stripe SET first_row_number = COLUMNAR_FIRST_ROW_NUMBER +
|
||||
(stripe_num - 1) * max_row_count;
|
||||
END;
|
||||
$$;
|
||||
|
||||
--#include "udfs/upgrade_columnar_storage/10.2-1.sql"
|
||||
CREATE OR REPLACE FUNCTION upgrade_columnar_storage(rel regclass)
|
||||
RETURNS VOID
|
||||
STRICT
|
||||
LANGUAGE c AS 'MODULE_PATHNAME', $$upgrade_columnar_storage$$;
|
||||
|
||||
COMMENT ON FUNCTION upgrade_columnar_storage(regclass)
|
||||
IS 'function to upgrade the columnar storage, if necessary';
|
||||
|
||||
|
||||
--#include "udfs/downgrade_columnar_storage/10.2-1.sql"
|
||||
|
||||
CREATE OR REPLACE FUNCTION downgrade_columnar_storage(rel regclass)
|
||||
RETURNS VOID
|
||||
STRICT
|
||||
LANGUAGE c AS 'MODULE_PATHNAME', $$downgrade_columnar_storage$$;
|
||||
|
||||
COMMENT ON FUNCTION downgrade_columnar_storage(regclass)
|
||||
IS 'function to downgrade the columnar storage, if necessary';
|
||||
|
||||
-- upgrade storage for all columnar relations
|
||||
SELECT upgrade_columnar_storage(c.oid) FROM pg_class c, pg_am a
|
||||
WHERE c.relam = a.oid AND amname = 'columnar';
|
||||
|
||||
-- columnar--10.2-1--10.2-2.sql
|
||||
|
||||
-- revoke read access for columnar.chunk from unprivileged
|
||||
-- user as it contains chunk min/max values
|
||||
REVOKE SELECT ON columnar.chunk FROM PUBLIC;
|
||||
|
||||
|
||||
-- columnar--10.2-2--10.2-3.sql
|
||||
|
||||
-- Since stripe_first_row_number_idx is required to scan a columnar table, we
|
||||
-- need to make sure that it is created before doing anything with columnar
|
||||
-- tables during pg upgrades.
|
||||
--
|
||||
-- However, a plain btree index is not a dependency of a table, so pg_upgrade
|
||||
-- cannot guarantee that stripe_first_row_number_idx gets created when
|
||||
-- creating columnar.stripe, unless we make it a unique "constraint".
|
||||
--
|
||||
-- To do that, drop stripe_first_row_number_idx and create a unique
|
||||
-- constraint with the same name to keep the code change at minimum.
|
||||
DROP INDEX columnar.stripe_first_row_number_idx;
|
||||
ALTER TABLE columnar.stripe ADD CONSTRAINT stripe_first_row_number_idx
|
||||
UNIQUE (storage_id, first_row_number);
|
||||
|
||||
-- columnar--10.2-3--10.2-4.sql
|
||||
|
||||
CREATE OR REPLACE FUNCTION columnar_ensure_am_depends_catalog()
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
SET search_path = pg_catalog
|
||||
AS $func$
|
||||
BEGIN
|
||||
INSERT INTO pg_depend
|
||||
SELECT -- Define a dependency edge from "columnar table access method" ..
|
||||
'pg_am'::regclass::oid as classid,
|
||||
(select oid from pg_am where amname = 'columnar') as objid,
|
||||
0 as objsubid,
|
||||
-- ... to each object that is registered to pg_class and that lives
|
||||
-- in "columnar" schema. That contains catalog tables, indexes
|
||||
-- created on them and the sequences created in "columnar" schema.
|
||||
--
|
||||
-- Given the possibility of user might have created their own objects
|
||||
-- in columnar schema, we explicitly specify list of objects that we
|
||||
-- are interested in.
|
||||
'pg_class'::regclass::oid as refclassid,
|
||||
columnar_schema_members.relname::regclass::oid as refobjid,
|
||||
0 as refobjsubid,
|
||||
'n' as deptype
|
||||
FROM (VALUES ('columnar.chunk'),
|
||||
('columnar.chunk_group'),
|
||||
('columnar.chunk_group_pkey'),
|
||||
('columnar.chunk_pkey'),
|
||||
('columnar.options'),
|
||||
('columnar.options_pkey'),
|
||||
('columnar.storageid_seq'),
|
||||
('columnar.stripe'),
|
||||
('columnar.stripe_first_row_number_idx'),
|
||||
('columnar.stripe_pkey')
|
||||
) columnar_schema_members(relname)
|
||||
-- Avoid inserting duplicate entries into pg_depend.
|
||||
EXCEPT TABLE pg_depend;
|
||||
END;
|
||||
$func$;
|
||||
COMMENT ON FUNCTION columnar_ensure_am_depends_catalog()
|
||||
IS 'internal function responsible for creating dependencies from columnar '
|
||||
'table access method to the rel objects in columnar schema';
|
||||
|
||||
|
||||
SELECT columnar_ensure_am_depends_catalog();
|
Loading…
Reference in New Issue