static
void OGR2SQLITE_ST_AsBinary(sqlite3_context* pContext,
                            int argc, sqlite3_value** argv)
{
    OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL);
    if( poGeom != NULL )
    {
        int nBLOBLen = poGeom->WkbSize();
        GByte* pabyGeomBLOB = (GByte*) VSIMalloc(nBLOBLen);
        if( pabyGeomBLOB != NULL )
        {
            if( poGeom->exportToWkb(wkbNDR, pabyGeomBLOB) == OGRERR_NONE )
                sqlite3_result_blob( pContext, pabyGeomBLOB, nBLOBLen, CPLFree);
            else
            {
                VSIFree(pabyGeomBLOB);
                sqlite3_result_null (pContext);
            }
        }
        else
            sqlite3_result_null (pContext);
        delete poGeom;
    }
    else
        sqlite3_result_null (pContext);
}
OGRErr OGRSQLiteTableLayer::CreateFeature( OGRFeature *poFeature )

{
    sqlite3 *hDB = poDS->GetDB();
    CPLString      osCommand;
    CPLString      osValues;
    int            bNeedComma = FALSE;

    if (bSpatialiteReadOnly || !poDS->GetUpdate())
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "Can't create feature on a read-only layer.");
        return OGRERR_FAILURE;
    }

    ResetReading();

/* -------------------------------------------------------------------- */
/*      Form the INSERT command.                                        */
/* -------------------------------------------------------------------- */
    osCommand += CPLSPrintf( "INSERT INTO '%s' (", pszEscapedTableName );

/* -------------------------------------------------------------------- */
/*      Add FID if we have a cleartext FID column.                      */
/* -------------------------------------------------------------------- */
    if( pszFIDColumn != NULL // && !EQUAL(pszFIDColumn,"OGC_FID") 
        && poFeature->GetFID() != OGRNullFID )
    {
        osCommand += pszFIDColumn;

        osValues += CPLSPrintf( "%ld", poFeature->GetFID() );
        bNeedComma = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Add geometry.                                                   */
/* -------------------------------------------------------------------- */
    OGRGeometry *poGeom = poFeature->GetGeometryRef();

    if( osGeomColumn.size() != 0 &&
        poGeom != NULL &&
        eGeomFormat != OSGF_FGF )
    {

        if( bNeedComma )
        {
            osCommand += ",";
            osValues += ",";
        }

        osCommand += osGeomColumn;

        osValues += "?";

        bNeedComma = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Add field values.                                               */
/* -------------------------------------------------------------------- */
    int iField;
    int nFieldCount = poFeatureDefn->GetFieldCount();

    for( iField = 0; iField < nFieldCount; iField++ )
    {
        if( !poFeature->IsFieldSet( iField ) )
            continue;

        if( bNeedComma )
        {
            osCommand += ",";
            osValues += ",";
        }

        osCommand += "'";
        osCommand +=poFeatureDefn->GetFieldDefn(iField)->GetNameRef();
        osCommand += "'";

        osValues += "?";

        bNeedComma = TRUE;
    }

/* -------------------------------------------------------------------- */
/*      Merge final command.                                            */
/* -------------------------------------------------------------------- */
    osCommand += ") VALUES (";
    osCommand += osValues;
    osCommand += ")";

/* -------------------------------------------------------------------- */
/*      Prepare the statement.                                          */
/* -------------------------------------------------------------------- */
    int rc;
    sqlite3_stmt *hInsertStmt;

#ifdef DEBUG
    CPLDebug( "OGR_SQLITE", "prepare(%s)", osCommand.c_str() );
#endif

    rc = sqlite3_prepare( hDB, osCommand, -1, &hInsertStmt, NULL );
    if( rc != SQLITE_OK )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "In CreateFeature(): sqlite3_prepare(%s):\n  %s", 
                  osCommand.c_str(), sqlite3_errmsg(hDB) );

        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Bind the geometry                                               */
/* -------------------------------------------------------------------- */
    int nBindField = 1;

    if( osGeomColumn.size() != 0 &&
        poGeom != NULL &&
        eGeomFormat != OSGF_FGF )
    {
        if ( eGeomFormat == OSGF_WKT )
        {
            char *pszWKT = NULL;
            poGeom->exportToWkt( &pszWKT );
            rc = sqlite3_bind_text( hInsertStmt, nBindField++, pszWKT, -1, CPLFree );
        }
        else if( eGeomFormat == OSGF_WKB )
        {
            int nWKBLen = poGeom->WkbSize();
            GByte *pabyWKB = (GByte *) CPLMalloc(nWKBLen + 1);

            poGeom->exportToWkb( wkbNDR, pabyWKB );
            rc = sqlite3_bind_blob( hInsertStmt, nBindField++, pabyWKB, nWKBLen, CPLFree );
        }
        else if ( eGeomFormat == OSGF_SpatiaLite )
        {
            int     nBLOBLen;
            GByte   *pabySLBLOB;

            ExportSpatiaLiteGeometry( poGeom, nSRSId, wkbNDR, bHasM, 
                                      bSpatialite2D, &pabySLBLOB, &nBLOBLen );
            rc = sqlite3_bind_blob( hInsertStmt, nBindField++, pabySLBLOB,
                                    nBLOBLen, CPLFree );
        }
        else
        {
            CPLAssert(0);
        }

        if( rc != SQLITE_OK )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "sqlite3_bind_blob/text() failed:\n  %s", 
                      sqlite3_errmsg(hDB) );
            
            sqlite3_finalize( hInsertStmt );
            return OGRERR_FAILURE;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      Bind field values.                                              */
/* -------------------------------------------------------------------- */
    
    for( iField = 0; iField < nFieldCount; iField++ )
    {
        const char *pszRawValue;

        if( !poFeature->IsFieldSet( iField ) )
            continue;

        switch( poFeatureDefn->GetFieldDefn(iField)->GetType() )
        {
            case OFTInteger:
            {
                int nFieldVal = poFeature->GetFieldAsInteger( iField );
                rc = sqlite3_bind_int(hInsertStmt, nBindField++, nFieldVal);
                break;
            }
            
            case OFTReal:
            {
                double dfFieldVal = poFeature->GetFieldAsDouble( iField );
                rc = sqlite3_bind_double(hInsertStmt, nBindField++, dfFieldVal);
                break;
            }
            
            case OFTBinary:
            {
                int nDataLength = 0;
                GByte* pabyData =
                    poFeature->GetFieldAsBinary( iField, &nDataLength );
                rc = sqlite3_bind_blob(hInsertStmt, nBindField++,
                                       pabyData, nDataLength, SQLITE_TRANSIENT);
                break;
            }
            
            default:
            {
                pszRawValue = poFeature->GetFieldAsString( iField );
                rc = sqlite3_bind_text(hInsertStmt, nBindField++,
                                       pszRawValue, -1, SQLITE_TRANSIENT);
                break;
            }
        }
        
        if( rc != SQLITE_OK )
        {
            CPLError( CE_Failure, CPLE_AppDefined, 
                      "sqlite3_bind_() for column %s failed:\n  %s", 
                      poFeatureDefn->GetFieldDefn(iField)->GetNameRef(),
                      sqlite3_errmsg(hDB) );
            
            sqlite3_finalize( hInsertStmt );
            return OGRERR_FAILURE;
        }
    }

/* -------------------------------------------------------------------- */
/*      Execute the insert.                                             */
/* -------------------------------------------------------------------- */
    rc = sqlite3_step( hInsertStmt );

    if( rc != SQLITE_OK && rc != SQLITE_DONE )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "sqlite3_step() failed:\n  %s", 
                  sqlite3_errmsg(hDB) );
                  
        sqlite3_finalize( hInsertStmt );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Capture the FID/rowid.                                          */
/* -------------------------------------------------------------------- */
    const sqlite_int64 nFID = sqlite3_last_insert_rowid( hDB );
    if(nFID > 0)
    {
        poFeature->SetFID( (long)nFID ); /* Possible truncation if nFID is 64bit */
    }

    sqlite3_finalize( hInsertStmt );

    return OGRERR_NONE;
}