The Polypheny Go Driver connects Go applications to Polypheny over the Prism Query Interface. It supports SQL through Go’s database/sql package. A driver-specific connection API exposes MongoQL reads and Prism entity metadata.
Installation and compatibility
Use Go 1.23 or newer and a running Polypheny instance with the Prism TCP interface enabled. This page documents driver version v0.1.0, which includes the Prism 2.2 Go bindings. The driver checks the server’s compatibility response when opening a connection. Document collection metadata requires server-side support for the Prism 2.2 document metadata fields.
From an existing Go module, install the driver with the following command.
go get github.com/polypheny/Polypheny-Go-Driver@v0.1.0
Import github.com/polypheny/Polypheny-Go-Driver to register the driver as polypheny. Use a blank import for SQL-only applications, or import the package as polypheny to access its types. For a complete SQL application with setup and transaction examples, see Integrating a Go Application with Polypheny.
Connection settings
Pass polypheny and a DSN in the form host:port,username:password to sql.Open. The default Prism TCP port is 20590. For a local instance with user pa and an empty password, the DSN is localhost:20590,pa:. Keep the final colon when the password is empty. The DSN parser has no escape syntax for commas or colons in the username or password. To use an IPv6 address, enclose it in brackets before the port.
The driver uses unencrypted TCP. Use a trusted network or an encrypted tunnel, keep credentials out of source control, and avoid logging the DSN. Use PingContext to verify connectivity, credentials and protocol compatibility because sql.Open may return before it connects. Reuse the resulting *sql.DB as the application connection pool and close it at shutdown.
SQL execution
| Task | database/sql API |
|---|---|
| Read a single row | QueryRowContext, then Scan. Check sql.ErrNoRows when the query matches no rows. |
| Read multiple rows | QueryContext, then Next and Scan. Close the rows and check Err after iteration. |
| Run a statement that returns an update count | ExecContext. Use RowsAffected for writes and provide generated IDs explicitly when needed. LastInsertId returns an unsupported-operation error. |
| Reuse a parameterized statement | PrepareContext, then ExecContext, QueryContext, or QueryRowContext on the *sql.Stmt. Close the statement when finished. |
| Group operations in a transaction | BeginTx, then execute all operations through the returned *sql.Tx. Finish with Commit or Rollback. |
Use ? for positional SQL parameters and pass values in placeholder order. The driver rejects named arguments such as sql.Named. Statements outside an explicit transaction use auto-commit. The driver accepts the default transaction isolation level with ReadOnly false and rejects nested transactions. The driver fetches all Prism pages and buffers the full result before handing rows to database/sql. Use SQL filters and limits for large results.
SQL value conversions
After the standard database/sql argument conversion, the driver accepts nil, bool, int64, float64, string, []byte and time.Time. A nil []byte becomes SQL NULL. The driver sends time.Time values as Prism timestamps with millisecond precision. Bind variables represent values. Use fixed SQL or validate identifiers separately when constructing a query.
| Prism result | Value supplied to Scan |
|---|---|
NULL |
nil. Use a nullable scan destination such as sql.NullString when the column can contain NULL. |
| Boolean | bool |
| Integer, long | int64 |
| Float, double | float64 |
| String | string |
| Binary, file | []byte |
| Date, time, timestamp | time.Time in UTC. A time of day is anchored to the Unix epoch date. |
| Decimal | Exact string, which can use exponent notation. Scan into a string to preserve precision. |
SQL row decoding supports the scalar values above. Use the document API for nested documents and arrays.
MongoQL and entity metadata
Reserve a connection with (*sql.DB).Conn, call (*sql.Conn).Raw, and assert the underlying connection as *polypheny.PolyphenyConn inside the callback. Keep the raw driver connection inside the callback and close the *sql.Conn to return it to the pool.
QueryMongoContextexecutes a MongoQL query in the server’s default namespace and returns a pointer to a slice of documents. It expects a document result and takes the query as a string, with no bind arguments or namespace parameter. Use fixed query text for the example below. Top-level map keys are strings even though the signature usesmap[any]any. Nested documents aremap[string]any, arrays are[]any, and numbers retain their Prism width asint32,int64,float32orfloat64. Decimal values remain strings.SearchEntitieslists entities in an explicitly named namespace. Passnilto list all entities, or pass a pointer to a name pattern.%matches any sequence and_matches a single character when used as wildcards. Inspect the returnedprism.EntitiesResponsewithGetEntitiesand useGetTableorGetDocumentto select the variant. The Go driver exposes no graph query API.
Document metadata
The generated prism package provides the response types. The server returns document fields inferred from a bounded sample of the collection. Treat the result as an observation of the current data. Empty collections can return no fields and no example document.
| Type | Go getter | Meaning |
|---|---|---|
Document |
GetNamespaceName() |
Namespace containing the collection. |
Document |
GetCollectionName() |
Collection name. |
Document |
GetFields() |
Observed field paths and types, as []*prism.DocumentField. |
Document |
GetSampleDocumentJson() |
Sample document as a JSON string. Check SampleDocumentJson != nil to distinguish a present value from an absent field. |
Document |
GetDocumentIndexes() |
Index metadata as []*prism.DocumentIndex, when exposed by the storage adapter. |
DocumentField |
GetFieldPath() |
Dotted path such as profile.city. The server escapes literal dots and backslashes within key names. |
DocumentField |
GetTypeName() |
Inferred type, for example string, int, double, bool, array, or object. The server can report null for a field observed only with null values or mixed for incompatible observed types. |
DocumentField |
GetIsOptional() |
Whether the sample contained a missing or null value for the path. |
DocumentIndex |
GetFieldPath() |
Indexed field path. |
DocumentIndex |
GetIndexType() |
Index method name reported by the adapter. |
DocumentIndex |
GetUnique() |
Whether the adapter reports the indexed field as unique. |
Example
In a test instance with public as the default namespace, run these statements in the SQL console to create the example fixtures.
CREATE TABLE public.go_driver_people (id INTEGER PRIMARY KEY, name VARCHAR(40));
INSERT INTO public.go_driver_people (id, name) VALUES (1, 'Ada');
CREATE DOCUMENT NAMESPACE go_driver_documents;
Select go_driver_documents in the MongoQL console and run each of these commands individually.
db.createCollection("people")
db.people.insertOne({"name": "Ada", "profile": {"city": "Basel"}})
db.people.insertOne({"name": "Lin"})
Save this program as main.go in a Go module with the driver installed. The example reads the relational table as documents and inspects the separate document collection’s metadata.
package main
import (
"context"
"database/sql"
"fmt"
"log"
"time"
polypheny "github.com/polypheny/Polypheny-Go-Driver"
)
func inspect(ctx context.Context, db *sql.DB) error {
conn, err := db.Conn(ctx)
if err != nil {
return err
}
defer conn.Close()
return conn.Raw(func(raw any) error {
driverConn, ok := raw.(*polypheny.PolyphenyConn)
if !ok {
return fmt.Errorf("unexpected driver connection %T", raw)
}
rows, err := driverConn.QueryMongoContext(ctx, `db.go_driver_people.find({id: 1})`)
if err != nil {
return err
}
for _, row := range *rows {
fmt.Println("Name:", row["name"])
}
pattern := "people"
response, err := driverConn.SearchEntities(ctx, "go_driver_documents", &pattern)
if err != nil {
return err
}
for _, entity := range response.GetEntities() {
document := entity.GetDocument()
if document == nil {
continue
}
fmt.Printf("Collection: %s.%s\n", document.GetNamespaceName(), document.GetCollectionName())
for _, field := range document.GetFields() {
fmt.Printf("%s: %s (optional=%t)\n", field.GetFieldPath(), field.GetTypeName(), field.GetIsOptional())
}
if document.SampleDocumentJson != nil {
fmt.Println("Sample:", document.GetSampleDocumentJson())
}
for _, index := range document.GetDocumentIndexes() {
fmt.Printf("Index on %s: %s (unique=%t)\n", index.GetFieldPath(), index.GetIndexType(), index.GetUnique())
}
}
return nil
})
}
func run() error {
db, err := sql.Open("polypheny", "localhost:20590,pa:")
if err != nil {
return err
}
defer db.Close()
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
return inspect(ctx, db)
}
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
go run .
The example prints Ada from the relational table and reports profile.city as an optional string field in the document collection. The sample contents and available indexes depend on the storage adapter and the data.
To remove the example fixtures, run these statements in the SQL console.
DROP NAMESPACE go_driver_documents;
DROP TABLE public.go_driver_people;
Driver API reference
Use database/sql for application-level SQL. The exported driver objects below implement database/sql/driver and back the standard library’s connection, statement, transaction and row types. The package exposes no standalone functions.
| Type | Method | Behavior |
|---|---|---|
PolyphenyDriver |
Open(name string) (driver.Conn, error) |
Parses the DSN and opens a Prism connection with a background context. |
PolyphenyDriver |
OpenConnector(name string) (driver.Connector, error) |
Parses the DSN and returns a reusable connector. |
*Connector |
Connect(ctx context.Context) (driver.Conn, error) |
Opens, authenticates and negotiates the Prism connection. |
*Connector |
Driver() driver.Driver |
Returns the underlying PolyphenyDriver. |
*PolyphenyConn |
IsValid() bool |
Reports whether the connection remains eligible for reuse by the pool. |
*PolyphenyConn |
Ping(ctx context.Context) error |
Checks that the Prism server responds on this connection. |
*PolyphenyConn |
Prepare(query string) (driver.Stmt, error) |
Prepares SQL with a background context. |
*PolyphenyConn |
PrepareContext(ctx context.Context, query string) (driver.Stmt, error) |
Prepares SQL with positional parameters on the server. |
*PolyphenyConn |
Close() error |
Disconnects and releases the TCP connection. |
*PolyphenyConn |
Begin() (driver.Tx, error) |
Starts a transaction using the default options and a background context. |
*PolyphenyConn |
BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) |
Starts a transaction by disabling auto-commit. Accepts the default isolation level and ReadOnly: false. |
*PolyphenyConn |
Exec(query string, args []driver.Value) (driver.Result, error) |
Executes SQL with a background context and returns an update count. |
*PolyphenyConn |
ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) |
Executes SQL, using a prepared statement when positional arguments are supplied. Returns an update count. |
*PolyphenyConn |
Query(query string, args []driver.Value) (driver.Rows, error) |
Queries SQL rows with a background context. |
*PolyphenyConn |
QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) |
Queries SQL rows, using a prepared statement when positional arguments are supplied. |
*PolyphenyConn |
QueryMongoContext(ctx context.Context, query string) (*[]map[any]any, error) |
Runs a MongoQL query and returns its documents. |
*PolyphenyConn |
SearchEntities(ctx context.Context, namespace string, pattern *string) (*prism.EntitiesResponse, error) |
Lists entities and their Prism metadata in one namespace. |
*PreparedStatement |
Close() error |
Releases the prepared statement on the server. |
*PreparedStatement |
NumInput() int |
Returns the number of positional parameters. |
*PreparedStatement |
Exec(args []driver.Value) (driver.Result, error) |
Executes prepared SQL with a background context and returns an update count. |
*PreparedStatement |
ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) |
Executes prepared SQL with positional arguments and returns an update count. |
*PreparedStatement |
Query(args []driver.Value) (driver.Rows, error) |
Queries prepared SQL rows with a background context. |
*PreparedStatement |
QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) |
Queries prepared SQL rows with positional arguments. |
*PolyphenyRows |
Columns() []string |
Returns the SQL column labels, falling back to column names. |
*PolyphenyRows |
Close() error |
Closes the buffered row iterator. |
*PolyphenyRows |
Next(dest []driver.Value) error |
Copies the next row into dest, returning io.EOF when exhausted. |
*PolyphenyResult |
RowsAffected() (int64, error) |
Returns the update count. |
*PolyphenyResult |
LastInsertId() (int64, error) |
Returns -1 and an unsupported-operation error. |
*PolyphenyTransaction |
Commit() error |
Commits the transaction and restores auto-commit. |
*PolyphenyTransaction |
Rollback() error |
Rolls back the transaction and restores auto-commit. |
*ClientError |
Error() string |
Returns the error message. |
ArgSpec represents a prepared statement parameter internally and exposes no fields or methods. See the versioned Go API documentation for symbol declarations and the Prism Protocol for wire types.
Error handling
Check errors from the context-aware methods, Scan, Rows.Err, and transaction completion. The driver can return *polypheny.ClientError for server and driver errors. Use errors.As to identify it. Context and network errors can also occur. A timeout or cancellation during the Prism exchange can invalidate the underlying connection so the pool can open a replacement. Check server-side effects before retrying a write after a connection failure.