Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to Postgres for PGlite #1

Draft
wants to merge 13 commits into
base: base
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Global excludes across all subdirectories
*.o
*.wasm
*.obj
*.bc
*.so
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.shlib
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,13 @@ ifeq ($(PORTNAME), darwin)
ifneq ($(SO_MAJOR_VERSION), 0)
version_link = -compatibility_version $(SO_MAJOR_VERSION) -current_version $(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)
endif
LINK.shared = $(COMPILER) -dynamiclib -install_name '$(libdir)/lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX)' $(version_link) $(exported_symbols_list) -multiply_defined suppress
LINK.shared = $(COMPILER) -dynamiclib -install_name '$(libdir)/lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX)' $(version_link) $(exported_symbols_list)
shlib = lib$(NAME).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION)$(DLSUFFIX)
shlib_major = lib$(NAME).$(SO_MAJOR_VERSION)$(DLSUFFIX)
else
# loadable module
DLSUFFIX = .so
LINK.shared = $(COMPILER) -bundle -multiply_defined suppress
LINK.shared = $(COMPILER) -bundle
endif
BUILD.exports = $(AWK) '/^[^\#]/ {printf "_%s\n",$$1}' $< >$@
exports_file = $(SHLIB_EXPORTS:%.txt=%.list)
Expand Down
10 changes: 9 additions & 1 deletion src/backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,16 @@ ifneq ($(PORTNAME), cygwin)
ifneq ($(PORTNAME), win32)
ifneq ($(PORTNAME), aix)

OBJS += \
$(top_builddir)/src/pl/plpgsql/src/pl_comp.o \
$(top_builddir)/src/pl/plpgsql/src/pl_exec.o \
$(top_builddir)/src/pl/plpgsql/src/pl_funcs.o \
$(top_builddir)/src/pl/plpgsql/src/pl_gram.o \
$(top_builddir)/src/pl/plpgsql/src/pl_handler.o \
$(top_builddir)/src/pl/plpgsql/src/pl_scanner.o

postgres: $(OBJS)
$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -o $@
$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -sALLOW_MEMORY_GROWTH=1 -sFORCE_FILESYSTEM=1 -lnodefs.js -lproxyfs.js -lidbfs.js -o $@

endif
endif
Expand Down
2 changes: 2 additions & 0 deletions src/backend/access/heap/rewriteheap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,8 @@ CheckPointLogicalRewriteHeap(void)
struct dirent *mapping_de;
char path[MAXPGPATH + 20];

return;

/*
* We start of with a minimum of the last redo pointer. No new decoding
* slot will start before that, so that's a safe upper bound for removal.
Expand Down
24 changes: 24 additions & 0 deletions src/backend/bootstrap/bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ AuxiliaryProcessMain(int argc, char *argv[])
proc_exit(1);
}

checkDataDir();
ChangeToDataDir();

/*
* Validate we have been given a reasonable-looking DataDir and change
* into it (if under postmaster, should be done already).
Expand Down Expand Up @@ -501,6 +504,25 @@ BootstrapModeMain(void)
Assert(!IsUnderPostmaster);
Assert(IsBootstrapProcessingMode());

printf("NAMEDATALEN = %d\n", NAMEDATALEN);
printf("SIZEOF_POINTER = %d\n", (int) sizeof(Pointer));
printf("ALIGNOF_POINTER = %s\n", (sizeof(Pointer) == 4) ? "i" : "d");
printf("FLOAT8PASSBYVAL = %s\n", FLOAT8PASSBYVAL ? "true" : "false");
// Results on wasm:
// NAMEDATALEN = 64
// SIZEOF_POINTER = 4
// ALIGNOF_POINTER = i
// FLOAT8PASSBYVAL = false
// Trying to use following for other bki substitutions:
// POSTGRES = 'postgres'
// ENCODING = 6 // PG_UTF8
// LC_COLLATE = 'C'
// LC_CTYPE = 'en_US.UTF-8'
//

// manually substituted and embedded during build:
FILE *in = fopen("/usr/local/pgsql/share/postgres_wasm.bki","r");

/*
* To ensure that src/common/link-canary.c is linked into the backend, we
* must call it from somewhere. Here is as good as anywhere.
Expand All @@ -526,6 +548,8 @@ BootstrapModeMain(void)
* Process bootstrap input.
*/
StartTransactionCommand();

boot_yyset_in(in);
boot_yyparse();
CommitTransactionCommand();

Expand Down
3 changes: 3 additions & 0 deletions src/backend/libpq/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1864,6 +1864,9 @@ ident_inet(hbaPort *port)
static int
auth_peer(hbaPort *port)
{

return STATUS_OK;

uid_t uid;
gid_t gid;
#ifndef WIN32
Expand Down
106 changes: 106 additions & 0 deletions src/backend/libpq/pqcomm.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@
#include "utils/guc.h"
#include "utils/memutils.h"

#ifdef EMSCRIPTEN
#include <emscripten.h>
#endif

/*
* Cope with the various platform-specific ways to spell TCP keepalive socket
* options. This doesn't cover Windows, which as usual does its own thing.
Expand Down Expand Up @@ -149,11 +153,28 @@ static void socket_putmessage_noblock(char msgtype, const char *s, size_t len);
static int internal_putbytes(const char *s, size_t len);
static int internal_flush(void);

static void emscripten_comm_reset(void);
static int emscripten_flush(void);
static int emscripten_flush_if_writable(void);
static bool emscripten_is_send_pending(void);
static int emscripten_putmessage(char msgtype, const char *s, size_t len);
static void emscripten_putmessage_noblock(char msgtype, const char *s, size_t len);

#ifdef HAVE_UNIX_SOCKETS
static int Lock_AF_UNIX(const char *unixSocketDir, const char *unixSocketPath);
static int Setup_AF_UNIX(const char *sock_path);
#endif /* HAVE_UNIX_SOCKETS */

#ifdef EMSCRIPTEN
static const PQcommMethods PqCommSocketMethods = {
emscripten_comm_reset,
emscripten_flush,
emscripten_flush_if_writable,
emscripten_is_send_pending,
emscripten_putmessage,
emscripten_putmessage_noblock
};
#else
static const PQcommMethods PqCommSocketMethods = {
socket_comm_reset,
socket_flush,
Expand All @@ -162,12 +183,97 @@ static const PQcommMethods PqCommSocketMethods = {
socket_putmessage,
socket_putmessage_noblock
};
#endif

const PQcommMethods *PqCommMethods = &PqCommSocketMethods;

WaitEventSet *FeBeWaitSet;


/* --------------------------------
* Emscripten implementation
* --------------------------------
*/

static StringInfoData emscripten_buffer;
static bool emscripten_buffer_is_initialized = false;
static bool emscripten_buffer_busy = false;

#ifdef EMSCRIPTEN
EM_JS(void, emscripten_dispatch_result, (char *res, int len), {
// Dispatch the result to JS land
if (!Module.eventTarget) return;
var heapBytes = new Uint8Array(Module.HEAPU8.buffer, res, len);
var resultBytes = new Uint8Array(heapBytes);
Module.eventTarget.dispatchEvent(new Module.Event("result", {
detail: resultBytes
}));
});
#endif

static void emscripten_init_buffer(void) {
if (!emscripten_buffer_is_initialized) {
initStringInfo(&emscripten_buffer);
emscripten_buffer_is_initialized = true;
}
}

static void emscripten_comm_reset(void) {
if (emscripten_buffer_is_initialized) {
resetStringInfo(&emscripten_buffer);
} else {
emscripten_init_buffer();
}
}

static int emscripten_flush(void) {
if (emscripten_buffer.len > 0) {
emscripten_dispatch_result(emscripten_buffer.data, emscripten_buffer.len);
resetStringInfo(&emscripten_buffer);
}
return 0;
}

static int emscripten_flush_if_writable(void) {
return emscripten_flush();
return 0;
}

static bool emscripten_is_send_pending(void) {
return emscripten_buffer.len > 0;
}

static int emscripten_putmessage(char msgtype, const char *s, size_t len) {
if (emscripten_buffer_busy)
return 0;
emscripten_buffer_busy = true;

emscripten_init_buffer();

uint32 n32;
Assert(msgtype != 0);

appendStringInfoChar(&emscripten_buffer, msgtype);
n32 = pg_hton32((uint32) (len + 4));
appendBinaryStringInfo(&emscripten_buffer, (char *) &n32, 4);
appendBinaryStringInfo(&emscripten_buffer, s, len);

emscripten_buffer_busy = false;

// Flush buffer on every message
emscripten_flush();

return 0;

fail:
emscripten_buffer_busy = false;
return EOF;
}

static void emscripten_putmessage_noblock(char msgtype, const char *s, size_t len) {
emscripten_putmessage(msgtype, s, len);
}

/* --------------------------------
* pq_init - initialize libpq at backend startup
* --------------------------------
Expand Down
5 changes: 5 additions & 0 deletions src/backend/main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
#include "utils/pg_locale.h"
#include "utils/ps_status.h"

#ifdef EMSCRIPTEN
#include <emscripten.h>
#endif

const char *progname;

Expand Down Expand Up @@ -366,6 +369,8 @@ help(const char *progname)
static void
check_root(const char *progname)
{
return;

#ifndef WIN32
if (geteuid() == 0)
{
Expand Down
23 changes: 23 additions & 0 deletions src/backend/port/sysv_sema.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, int numSems)
{
int semId;

return 42;

semId = semget(semKey, numSems, IPC_CREAT | IPC_EXCL | IPCProtection);

if (semId < 0)
Expand Down Expand Up @@ -147,6 +149,8 @@ IpcSemaphoreInitialize(IpcSemaphoreId semId, int semNum, int value)
{
union semun semun;

return;

semun.val = value;
if (semctl(semId, semNum, SETVAL, semun) < 0)
{
Expand All @@ -170,6 +174,8 @@ IpcSemaphoreKill(IpcSemaphoreId semId)
{
union semun semun;

return;

semun.val = 0; /* unused, but keep compiler quiet */

if (semctl(semId, 0, IPC_RMID, semun) < 0)
Expand All @@ -182,6 +188,8 @@ IpcSemaphoreGetValue(IpcSemaphoreId semId, int semNum)
{
union semun dummy; /* for Solaris */

return 0;

dummy.val = 0; /* unused */

return semctl(semId, semNum, GETVAL, dummy);
Expand All @@ -193,6 +201,8 @@ IpcSemaphoreGetLastPID(IpcSemaphoreId semId, int semNum)
{
union semun dummy; /* for Solaris */

return 42;

dummy.val = 0; /* unused */

return semctl(semId, semNum, GETPID, dummy);
Expand All @@ -215,6 +225,8 @@ IpcSemaphoreCreate(int numSems)
union semun semun;
PGSemaphoreData mysema;

return 42;

/* Loop till we find a free IPC key */
for (nextSemaKey++;; nextSemaKey++)
{
Expand Down Expand Up @@ -314,6 +326,7 @@ void
PGReserveSemaphores(int maxSemas)
{
struct stat statbuf;
return;

/*
* We use the data directory's inode number to seed the search for free
Expand Down Expand Up @@ -359,6 +372,8 @@ ReleaseSemaphores(int status, Datum arg)
{
int i;

return;

for (i = 0; i < numSemaSets; i++)
IpcSemaphoreKill(mySemaSets[i]);
free(mySemaSets);
Expand All @@ -373,6 +388,7 @@ PGSemaphore
PGSemaphoreCreate(void)
{
PGSemaphore sema;
return sema;

/* Can't do this in a backend, because static state is postmaster's */
Assert(!IsUnderPostmaster);
Expand Down Expand Up @@ -407,6 +423,7 @@ PGSemaphoreCreate(void)
void
PGSemaphoreReset(PGSemaphore sema)
{
return;
IpcSemaphoreInitialize(sema->semId, sema->semNum, 0);
}

Expand All @@ -421,6 +438,8 @@ PGSemaphoreLock(PGSemaphore sema)
int errStatus;
struct sembuf sops;

return;

sops.sem_op = -1; /* decrement */
sops.sem_flg = 0;
sops.sem_num = sema->semNum;
Expand Down Expand Up @@ -454,6 +473,8 @@ PGSemaphoreUnlock(PGSemaphore sema)
int errStatus;
struct sembuf sops;

return;

sops.sem_op = 1; /* increment */
sops.sem_flg = 0;
sops.sem_num = sema->semNum;
Expand Down Expand Up @@ -484,6 +505,8 @@ PGSemaphoreTryLock(PGSemaphore sema)
int errStatus;
struct sembuf sops;

return true;

sops.sem_op = -1; /* decrement */
sops.sem_flg = IPC_NOWAIT; /* but don't block */
sops.sem_num = sema->semNum;
Expand Down