mirror of https://github.com/citusdata/citus.git
Don't rely on gcc-specific features (#1963)
* Don't use expressions inside compound statements * Don't depend on __builtin_constant_p * Remove reliance on S_ISLNK * Replace use of __func__: older mcvs doesn't support this builtinpull/1975/head
parent
59a03d809d
commit
76d1edc3fd
|
@ -44,6 +44,8 @@ static const char *CitusNodeTagNamesD[] = {
|
|||
|
||||
const char **CitusNodeTagNames = CitusNodeTagNamesD;
|
||||
|
||||
/* support for CitusNewNode() macro */
|
||||
CitusNode *newCitusNodeMacroHolder;
|
||||
|
||||
/* exports for SQL callable functions */
|
||||
PG_FUNCTION_INFO_V1(citus_extradata_container);
|
||||
|
|
|
@ -73,6 +73,7 @@ static void OutputBinaryHeaders(FileOutputStream *partitionFileArray, uint32 fil
|
|||
static void OutputBinaryFooters(FileOutputStream *partitionFileArray, uint32 fileCount);
|
||||
static uint32 RangePartitionId(Datum partitionValue, const void *context);
|
||||
static uint32 HashPartitionId(Datum partitionValue, const void *context);
|
||||
static bool FileIsLink(char *filename, struct stat filestat);
|
||||
|
||||
|
||||
/* exports for SQL callable functions */
|
||||
|
@ -614,6 +615,25 @@ CitusCreateDirectory(StringInfo directoryName)
|
|||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
static bool
|
||||
FileIsLink(char *filename, struct stat filestat)
|
||||
{
|
||||
return pgwin32_is_junction(filename);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
static bool
|
||||
FileIsLink(char *filename, struct stat filestat)
|
||||
{
|
||||
return S_ISLNK(filestat.st_mode);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* CitusRemoveDirectory first checks if the given directory exists. If it does, the
|
||||
* function recursively deletes the contents of the given directory, and then
|
||||
|
@ -645,7 +665,7 @@ CitusRemoveDirectory(StringInfo filename)
|
|||
* content, recurse into this function. Also, make sure that we do not
|
||||
* recurse into symbolic links.
|
||||
*/
|
||||
if (S_ISDIR(fileStat.st_mode) && !S_ISLNK(fileStat.st_mode))
|
||||
if (S_ISDIR(fileStat.st_mode) && !FileIsLink(filename->data, fileStat))
|
||||
{
|
||||
const char *directoryName = filename->data;
|
||||
struct dirent *directoryEntry = NULL;
|
||||
|
|
|
@ -89,6 +89,11 @@ CitusNodeTagI(Node *node)
|
|||
return ((CitusNode*)(node))->citus_tag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Postgres's nodes/nodes.h has more information on why we do this.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
|
||||
/* Citus variant of newNode(), don't use directly. */
|
||||
#define CitusNewNode(size, tag) \
|
||||
({ CitusNode *_result; \
|
||||
|
@ -100,6 +105,22 @@ CitusNodeTagI(Node *node)
|
|||
_result; \
|
||||
})
|
||||
|
||||
#else
|
||||
|
||||
extern CitusNode *newCitusNodeMacroHolder;
|
||||
|
||||
#define CitusNewNode(size, tag) \
|
||||
( \
|
||||
AssertMacro((size) >= sizeof(CitusNode)), /* need the tag, at least */ \
|
||||
newCitusNodeMacroHolder = (CitusNode *) palloc0fast(size), \
|
||||
newCitusNodeMacroHolder->extensible.type = T_ExtensibleNode, \
|
||||
newCitusNodeMacroHolder->extensible.extnodename = CitusNodeTagNames[tag - CITUS_NODE_TAG_START], \
|
||||
newCitusNodeMacroHolder->citus_tag =(int) (tag), \
|
||||
newCitusNodeMacroHolder \
|
||||
)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* IsA equivalent that compares node tags, including Citus-specific nodes.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#define ERRORMESSAGE_H
|
||||
|
||||
|
||||
#include "c.h"
|
||||
#include "distributed/citus_nodes.h"
|
||||
|
||||
|
||||
|
@ -34,7 +35,8 @@ typedef struct DeferredErrorMessage
|
|||
* serialized/copied/deserialized, i.e. can be embedded in plans and such.
|
||||
*/
|
||||
#define DeferredError(code, message, detail, hint) \
|
||||
DeferredErrorInternal(code, message, detail, hint, __FILE__, __LINE__, __func__)
|
||||
DeferredErrorInternal(code, message, detail, hint, __FILE__, __LINE__, \
|
||||
PG_FUNCNAME_MACRO)
|
||||
|
||||
DeferredErrorMessage * DeferredErrorInternal(int code, const char *message, const
|
||||
char *detail, const char *hint,
|
||||
|
@ -48,12 +50,22 @@ DeferredErrorMessage * DeferredErrorInternal(int code, const char *message, cons
|
|||
* The trickery with __builtin_constant_p/pg_unreachable aims to have the
|
||||
* compiler understand that the function will not return if elevel >= ERROR.
|
||||
*/
|
||||
#ifdef HAVE__BUILTIN_CONSTANT_P
|
||||
#define RaiseDeferredError(error, elevel) \
|
||||
do { \
|
||||
RaiseDeferredErrorInternal(error, elevel); \
|
||||
if (__builtin_constant_p(elevel) && (elevel) >= ERROR) { \
|
||||
pg_unreachable(); } \
|
||||
} while (0)
|
||||
#else /* !HAVE_BUILTIN_CONSTANT_P */
|
||||
#define RaiseDeferredError(error, elevel) \
|
||||
do { \
|
||||
const int elevel_ = (elevel); \
|
||||
RaiseDeferredErrorInternal(error, elevel_); \
|
||||
if (elevel_ >= ERROR) { \
|
||||
pg_unreachable(); } \
|
||||
} while (0)
|
||||
#endif /* HAVE_BUILTIN_CONSTANT_P */
|
||||
|
||||
void RaiseDeferredErrorInternal(DeferredErrorMessage *error, int elevel);
|
||||
|
||||
|
|
Loading…
Reference in New Issue