PLSwift
PLSwift copied to clipboard
Test PostgreSQL 12 compatibility
hello, I am reading your http://www.alwaysrightinstitute.com/plswift/ but I found that it is incompatible for postgresql 12. can you update your to support postgresql 12?
Need to check that out.
I tried to work on it for pgsql >= 12 in PGFunction.swift
public extension FunctionCallInfoBaseData {
/// Access PostgreSQL function call arguments as a Datum
subscript(datum idx: Int) -> Datum? {
// convert tuple to index
switch idx {
case 0: return args.0
case 1: return args.1
case 2: return args.2
case 3: return args.3
case 4: return args.4
case 5: return args.5
case 6: return args.6
case 7: return args.7
default: return nil
}
}
/// Access PostgreSQL function call arguments as an Int
subscript(int idx: Int) -> Int {
guard let datum = self[datum: idx] else { return -42 }
return datum.intValue
}
}
Structure changed from
typedef struct FunctionCallInfoData
{
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
fmNodePtr context; /* pass info about context of call */
fmNodePtr resultinfo; /* pass or return extra info about result */
Oid fncollation; /* collation for function to use */
bool isnull; /* function must set true if result is NULL */
short nargs; /* # arguments actually passed */
Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
bool argnull[FUNC_MAX_ARGS]; /* T if arg[i] is actually NULL */
} FunctionCallInfoData;
to
typedef struct FunctionCallInfoBaseData
{
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
fmNodePtr context; /* pass info about context of call */
fmNodePtr resultinfo; /* pass or return extra info about result */
Oid fncollation; /* collation for function to use */
#define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4
bool isnull; /* function must set true if result is NULL */
short nargs; /* # arguments actually passed */
#define FIELDNO_FUNCTIONCALLINFODATA_ARGS 6
NullableDatum args[FLEXIBLE_ARRAY_MEMBER];
} FunctionCallInfoBaseData;
Build log
# swift pl build
/root/helloswiftpl/.build/checkouts/PLSwift/Sources/PLSwift/PGFunction.swift:17:22: error: cannot find 'args' in scope
case 0: return args.0
^~~~
/root/helloswiftpl/.build/checkouts/PLSwift/Sources/PLSwift/PGFunction.swift:18:22: error: cannot find 'args' in scope
case 1: return args.1
^~~~
/root/helloswiftpl/.build/checkouts/PLSwift/Sources/PLSwift/PGFunction.swift:19:22: error: cannot find 'args' in scope
case 2: return args.2
^~~~
/root/helloswiftpl/.build/checkouts/PLSwift/Sources/PLSwift/PGFunction.swift:20:22: error: cannot find 'args' in scope
case 3: return args.3
^~~~
/root/helloswiftpl/.build/checkouts/PLSwift/Sources/PLSwift/PGFunction.swift:21:22: error: cannot find 'args' in scope
case 4: return args.4
^~~~
/root/helloswiftpl/.build/checkouts/PLSwift/Sources/PLSwift/PGFunction.swift:22:22: error: cannot find 'args' in scope
case 5: return args.5
^~~~
/root/helloswiftpl/.build/checkouts/PLSwift/Sources/PLSwift/PGFunction.swift:23:22: error: cannot find 'args' in scope
case 6: return args.6
^~~~
/root/helloswiftpl/.build/checkouts/PLSwift/Sources/PLSwift/PGFunction.swift:24:22: error: cannot find 'args' in scope
case 7: return args.7
^~~~
[1/1] Compiling PLSwift PGFunction.swift
It is strange args is not in scope. This is commit broke the lib https://github.com/postgres/postgres/commit/a9c35cf85ca1ff72f16f0f10d7ddee6e582b62b8
Swift has no way of dealing with args safely because there is no known length at compile time, and bounds checking would not work as it does with native Swift arrays.
To get this compiling I just commented out everything in this file. I think if I end up using this project at all, I will either write a C helper that fetches a certain argument and expose it to Swift, or will organise the code so that the low-level interactions with the postgres API happen in C and the business logic happens in Swift
Swift has no way of dealing with args safely because there is no known length at compile time, and bounds checking would not work as it does with native Swift arrays.
I don't understand that comment. Swift Array lengths are always dynamic and not known at compile time. The length of the pgarray is in nargs.
Presumably in the new setup it is not exposed as an args tuple anymore? When dealing w/ inline C arrays in Swift, you usually grab the start and then just index the values.
Would be nice to see what PG12 shows when cmd-clicking on a FunctionCallInfoBaseData (i.e. how it is exposed to Swift).