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

Test PostgreSQL 12 compatibility #3

Open
helje5 opened this issue Jul 17, 2020 · 3 comments
Open

Test PostgreSQL 12 compatibility #3

helje5 opened this issue Jul 17, 2020 · 3 comments
Labels
help wanted Extra attention is needed

Comments

@helje5
Copy link
Member

helje5 commented Jul 17, 2020

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.

@helje5 helje5 added the help wanted Extra attention is needed label Jul 17, 2020
@zloidemon
Copy link

zloidemon commented Nov 11, 2021

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 postgres/postgres@a9c35cf

@ephemer
Copy link

ephemer commented Jul 7, 2022

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

@helje5
Copy link
Member Author

helje5 commented Jul 7, 2022

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Development

No branches or pull requests

3 participants