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 builtin
pull/1975/head
Brian Cloutier 2018-01-23 17:03:29 -08:00 committed by GitHub
parent 59a03d809d
commit 76d1edc3fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 2 deletions

View File

@ -44,6 +44,8 @@ static const char *CitusNodeTagNamesD[] = {
const char **CitusNodeTagNames = CitusNodeTagNamesD; const char **CitusNodeTagNames = CitusNodeTagNamesD;
/* support for CitusNewNode() macro */
CitusNode *newCitusNodeMacroHolder;
/* exports for SQL callable functions */ /* exports for SQL callable functions */
PG_FUNCTION_INFO_V1(citus_extradata_container); PG_FUNCTION_INFO_V1(citus_extradata_container);

View File

@ -73,6 +73,7 @@ static void OutputBinaryHeaders(FileOutputStream *partitionFileArray, uint32 fil
static void OutputBinaryFooters(FileOutputStream *partitionFileArray, uint32 fileCount); static void OutputBinaryFooters(FileOutputStream *partitionFileArray, uint32 fileCount);
static uint32 RangePartitionId(Datum partitionValue, const void *context); static uint32 RangePartitionId(Datum partitionValue, const void *context);
static uint32 HashPartitionId(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 */ /* 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 * CitusRemoveDirectory first checks if the given directory exists. If it does, the
* function recursively deletes the contents of the given directory, and then * 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 * content, recurse into this function. Also, make sure that we do not
* recurse into symbolic links. * 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; const char *directoryName = filename->data;
struct dirent *directoryEntry = NULL; struct dirent *directoryEntry = NULL;

View File

@ -89,6 +89,11 @@ CitusNodeTagI(Node *node)
return ((CitusNode*)(node))->citus_tag; 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. */ /* Citus variant of newNode(), don't use directly. */
#define CitusNewNode(size, tag) \ #define CitusNewNode(size, tag) \
({ CitusNode *_result; \ ({ CitusNode *_result; \
@ -100,6 +105,22 @@ CitusNodeTagI(Node *node)
_result; \ _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. * IsA equivalent that compares node tags, including Citus-specific nodes.

View File

@ -11,6 +11,7 @@
#define ERRORMESSAGE_H #define ERRORMESSAGE_H
#include "c.h"
#include "distributed/citus_nodes.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. * serialized/copied/deserialized, i.e. can be embedded in plans and such.
*/ */
#define DeferredError(code, message, detail, hint) \ #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 DeferredErrorMessage * DeferredErrorInternal(int code, const char *message, const
char *detail, const char *hint, 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 * The trickery with __builtin_constant_p/pg_unreachable aims to have the
* compiler understand that the function will not return if elevel >= ERROR. * compiler understand that the function will not return if elevel >= ERROR.
*/ */
#ifdef HAVE__BUILTIN_CONSTANT_P
#define RaiseDeferredError(error, elevel) \ #define RaiseDeferredError(error, elevel) \
do { \ do { \
RaiseDeferredErrorInternal(error, elevel); \ RaiseDeferredErrorInternal(error, elevel); \
if (__builtin_constant_p(elevel) && (elevel) >= ERROR) { \ if (__builtin_constant_p(elevel) && (elevel) >= ERROR) { \
pg_unreachable(); } \ pg_unreachable(); } \
} while (0) } 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); void RaiseDeferredErrorInternal(DeferredErrorMessage *error, int elevel);