import asyncio
import pyngres.asyncio as py
...

# assume a session was started and connHandle is set. Also assume
# a transaction is already in progress and tranHandle has a value, or
# tranHandle is set to None, indicating the start of a new transaction

async def exec_SQL():
    '''execute an SQL statement with no parameters and returns no rows'''

    # encode the query so the DBMS can understand it
    query = (
        "CREATE TABLE foo " 
        "( name char(25), shipments integer, weight float )" )
    queryText = query.encode()

    # set up the parameter block; set connHandle and tranHandle
    qyp = py.IIAPI_QUERYPARM()
    qyp.qy_connHandle = connHandle
    qyp.qy_queryType = py.IIAPI_QT_QUERY    # indicate query execution
    qyp.qy_queryText = queryText
    qyp.qy_tranHandle = tranHandle

    # send the SQL to the DBMS
    await py.IIapi_query(qyp)
    # errors sending the SQL to the server are reported here
    status = qyp.qy_genParm.gp_status
    if not status == py.IIAPI_ST_SUCCESS:
        print(f'IIapi_query() error, {status=}')
        quit()

    tranHandle = qyp.qy_tranHandle
    stmtHandle = qyp.qy_stmtHandle

    # get the query status; syntax errors and references to
    # non-existent database assets are reported here
    gqp = py.IIAPI_GETQINFOPARM()
    gqp.gq_stmtHandle = stmtHandle
    await py.IIapi_getQueryInfo(gqp)
    status = gqp.gq_genParm.gp_status
    if not status == py.IIAPI_ST_SUCCESS:
        print(f'IIapi_getQueryInfo() error, {status=}')
        quit()

    # close the query to free the statement handle
    clp = py.IIAPI_CLOSEPARM()
    clp.cl_stmtHandle = stmtHandle
    await py.IIapi_close(clp)
    status = clp.cl_genParm.gp_status
    if not status == py.IIAPI_ST_SUCCESS:
        print(f'IIapi_close() error, {status=}')
        quit()

...
