/** * Delete the entry with the lowest expiration value * from the datacache right now. * * @param cls closure (our `struct Plugin`) * @return #GNUNET_OK on success, #GNUNET_SYSERR on error */ static int postgres_plugin_del (void *cls) { struct Plugin *plugin = cls; uint32_t size; uint32_t oid; struct GNUNET_HashCode key; PGresult *res; res = PQexecPrepared (plugin->dbh, "getm", 0, NULL, NULL, NULL, 1); if (GNUNET_OK != GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", "getm")) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Ending iteration (postgres error)\n"); return 0; } if (0 == PQntuples (res)) { /* no result */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Ending iteration (no more results)\n"); PQclear (res); return GNUNET_SYSERR; } if ((3 != PQnfields (res)) || (sizeof (size) != PQfsize (res, 0)) || (sizeof (oid) != PQfsize (res, 1)) || (sizeof (struct GNUNET_HashCode) != PQgetlength (res, 0, 2))) { GNUNET_break (0); PQclear (res); return 0; } size = ntohl (*(uint32_t *) PQgetvalue (res, 0, 0)); oid = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1)); memcpy (&key, PQgetvalue (res, 0, 2), sizeof (struct GNUNET_HashCode)); PQclear (res); if (GNUNET_OK != GNUNET_POSTGRES_delete_by_rowid (plugin->dbh, "delrow", oid)) return GNUNET_SYSERR; plugin->num_items--; plugin->env->delete_notify (plugin->env->cls, &key, size + OVERHEAD); return GNUNET_OK; }
static int pgsql_stmt_describe(pdo_stmt_t *stmt, int colno) { pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data; struct pdo_column_data *cols = stmt->columns; struct pdo_bound_param_data *param; char *str; if (!S->result) { return 0; } str = PQfname(S->result, colno); cols[colno].name = zend_string_init(str, strlen(str), 0); cols[colno].maxlen = PQfsize(S->result, colno); cols[colno].precision = PQfmod(S->result, colno); S->cols[colno].pgsql_type = PQftype(S->result, colno); switch (S->cols[colno].pgsql_type) { case BOOLOID: cols[colno].param_type = PDO_PARAM_BOOL; break; case OIDOID: /* did the user bind the column as a LOB ? */ if (stmt->bound_columns && ( (param = zend_hash_index_find_ptr(stmt->bound_columns, colno)) != NULL || (param = zend_hash_find_ptr(stmt->bound_columns, cols[colno].name)) != NULL)) { if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) { cols[colno].param_type = PDO_PARAM_LOB; break; } } cols[colno].param_type = PDO_PARAM_INT; break; case INT2OID: case INT4OID: cols[colno].param_type = PDO_PARAM_INT; break; case INT8OID: if (sizeof(zend_long)>=8) { cols[colno].param_type = PDO_PARAM_INT; } else { cols[colno].param_type = PDO_PARAM_STR; } break; case BYTEAOID: cols[colno].param_type = PDO_PARAM_LOB; break; default: cols[colno].param_type = PDO_PARAM_STR; } return 1; }
int CPgsqlResultHandler::extractValueAsInt(const int columnIndex) { char * valuePoint = PQgetvalue(m_res, m_currentResultIndex, columnIndex); int result = 0; if (PQbinaryTuples(m_res) == 1) { int nbBytes = PQfsize(m_res, columnIndex); switch (nbBytes) { case 8: result = Poco::ByteOrder::fromNetwork(*((Poco::Int64 *)valuePoint)); break; default: case 4: result = Poco::ByteOrder::fromNetwork(*((Poco::Int32 *)valuePoint)); break; case 2: result = Poco::ByteOrder::fromNetwork(*((Poco::Int16 *)valuePoint)); break; } } else { result = atoi(valuePoint); } return result; }
QSqlRecord QPSQLResult::record() const { QSqlRecord info; if (!isActive() || !isSelect()) return info; int count = PQnfields(d->result); for (int i = 0; i < count; ++i) { QSqlField f; if (d->driver->isUtf8) f.setName(QString::fromUtf8(PQfname(d->result, i))); else f.setName(QString::fromLocal8Bit(PQfname(d->result, i))); f.setType(qDecodePSQLType(PQftype(d->result, i))); int len = PQfsize(d->result, i); int precision = PQfmod(d->result, i); // swap length and precision if length == -1 if (len == -1 && precision > -1) { len = precision - 4; precision = -1; } f.setLength(len); f.setPrecision(precision); f.setSqlType(PQftype(d->result, i)); info.append(f); } return info; }
LispObj * Lisp_PQfsize(LispBuiltin *builtin) /* pq-fsize result field-number */ { int size, field; PGresult *res; LispObj *result, *field_number; field_number = ARGUMENT(1); result = ARGUMENT(0); if (!CHECKO(result, PGresult_t)) LispDestroy("%s: cannot convert %s to PGresult*", STRFUN(builtin), STROBJ(result)); res = (PGresult*)(result->data.opaque.data); CHECK_INDEX(field_number); field = FIXNUM_VALUE(field_number); size = PQfsize(res, field); return (INTEGER(size)); }
/* * Read in field descriptions from a libpq result set. * If self is not null, then also store the information. * If self is null, then just read, don't store. */ BOOL CI_read_fields_from_pgres(ColumnInfoClass *self, PGresult *pgres) { CSTR func = "CI_read_fields"; Int2 lf; int new_num_fields; OID new_adtid, new_relid = 0, new_attid = 0; Int2 new_adtsize; Int4 new_atttypmod = -1; char *new_field_name; /* at first read in the number of fields that are in the query */ new_num_fields = PQnfields(pgres); mylog("num_fields = %d\n", new_num_fields); if (self) { /* according to that allocate memory */ CI_set_num_fields(self, new_num_fields); if (NULL == self->coli_array) return FALSE; } /* now read in the descriptions */ for (lf = 0; lf < new_num_fields; lf++) { new_field_name = PQfname(pgres, lf); new_relid = PQftable(pgres, lf); new_attid = PQftablecol(pgres, lf); new_adtid = PQftype(pgres, lf); new_adtsize = PQfsize(pgres, lf); mylog("READING ATTTYPMOD\n"); new_atttypmod = PQfmod(pgres, lf); /* Subtract the header length */ switch (new_adtid) { case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIME: case PG_TYPE_TIME_WITH_TMZONE: break; default: new_atttypmod -= 4; } if (new_atttypmod < 0) new_atttypmod = -1; mylog("%s: fieldname='%s', adtid=%d, adtsize=%d, atttypmod=%d (rel,att)=(%d,%d)\n", func, new_field_name, new_adtid, new_adtsize, new_atttypmod, new_relid, new_attid); if (self) CI_set_field_info(self, lf, new_field_name, new_adtid, new_adtsize, new_atttypmod, new_relid, new_attid); } return TRUE; }
/* * call-seq: * res.fsize( index ) * * Returns the size of the field type in bytes. Returns <tt>-1</tt> if the field is variable sized. * * res = conn.exec("SELECT myInt, myVarChar50 FROM foo") * res.size(0) => 4 * res.size(1) => -1 */ static VALUE pgresult_fsize(VALUE self, VALUE index) { PGresult *result; int i = NUM2INT(index); result = pgresult_get(self); if (i < 0 || i >= PQnfields(result)) { rb_raise(rb_eArgError,"invalid field number %d", i); } return INT2NUM(PQfsize(result, i)); }
void show_column_info(PGresult* result) { int num_columns=0; int i; if(!result) return; num_columns=PQnfields(result); printf("%d columns in the result set\n",num_columns); for(i=0;i<num_columns;i++) printf("Field: %d,Name: %s,Internal size: %d\n", i, PQfname(result,i), PQfsize(result,i)); }
/* * Build "struct sqlda_compat" (metadata only) from PGresult * leaving enough space for the field values in * the given row number */ struct sqlda_compat * ecpg_build_compat_sqlda(int line, PGresult *res, int row, enum COMPAT_MODE compat) { struct sqlda_compat *sqlda; struct sqlvar_compat *sqlvar; char *fname; long size; int sqld; int i; size = sqlda_compat_total_size(res, row, compat); sqlda = (struct sqlda_compat *) ecpg_alloc(size, line); if (!sqlda) return NULL; memset(sqlda, 0, size); sqlvar = (struct sqlvar_compat *) (sqlda + 1); sqld = PQnfields(res); fname = (char *) (sqlvar + sqld); sqlda->sqld = sqld; ecpg_log("ecpg_build_compat_sqlda on line %d sqld = %d\n", line, sqld); sqlda->desc_occ = size; /* cheat here, keep the full allocated size */ sqlda->sqlvar = sqlvar; for (i = 0; i < sqlda->sqld; i++) { sqlda->sqlvar[i].sqltype = sqlda_dynamic_type(PQftype(res, i), compat); strcpy(fname, PQfname(res, i)); sqlda->sqlvar[i].sqlname = fname; fname += strlen(sqlda->sqlvar[i].sqlname) + 1; /* * this is reserved for future use, so we leave it empty for the time * being */ /* sqlda->sqlvar[i].sqlformat = (char *) (long) PQfformat(res, i); */ sqlda->sqlvar[i].sqlxid = PQftype(res, i); sqlda->sqlvar[i].sqltypelen = PQfsize(res, i); } return sqlda; }
/* ML type : pgresult_ -> int -> int */ EXTERNML value pq_fsize(value pgresval, value fieldno) { checkfbound(PGresult_val(pgresval), Long_val(fieldno), "pq_ftype"); return Val_long(PQfsize(PGresult_val(pgresval), Long_val(fieldno))); }
/************************************************************* *Returns the size in bytes of the field associated with the given field index. If the size returned is -1, the field is a variable length field. Field indices start at 0. *************************************************************/ int dbi_fieldsize(DBI_result *result_id, int field_num) { return(PQfsize(result_id, field_num)); }
GSQLCursorState pgsql_cursor_open (GSQLCursor *cursor) { GSQL_TRACE_FUNC; PGconn *pgconn; GSQLEPGSQLSession *e_session = NULL; GSQLEPGSQLCursor *e_cursor = NULL; GSQLEPGSQLVariable *e_var; GSQLVariable *var; GSQLWorkspace *workspace = NULL; PGSQL_FIELD *field; gulong n, n_fields, is_null = 1; gchar error_str[2048]; g_return_val_if_fail (GSQL_IS_CURSOR(cursor), GSQL_CURSOR_STATE_ERROR); g_return_val_if_fail (GSQL_IS_SESSION(cursor->session), GSQL_CURSOR_STATE_ERROR); e_session = cursor->session->spec; workspace = gsql_session_get_workspace (cursor->session); g_return_val_if_fail(GSQL_IS_WORKSPACE(workspace), GSQL_CURSOR_STATE_ERROR); pgconn = e_session->pgconn; if (!pgsql_cursor_prepare (cursor)) { return GSQL_CURSOR_STATE_ERROR; } e_cursor = cursor->spec; e_cursor->result = PQexec(e_session->pgconn, cursor->sql); if ( ! e_cursor->result ) { g_sprintf ( error_str, "Error occured: %s", pgsql_session_get_error(cursor->session) ); gsql_message_add (workspace, GSQL_MESSAGE_ERROR, error_str); return GSQL_CURSOR_STATE_ERROR; } pgsql_cursor_statement_detect (cursor); n_fields = PQnfields (e_cursor->result); if (n_fields == 0 && PQresultStatus(e_cursor->result) == PGRES_COMMAND_OK) return GSQL_CURSOR_STATE_OPEN; if (n_fields == 0 && PQresultStatus(e_cursor->result) != PGRES_COMMAND_OK) { g_sprintf ( error_str, "Error occured: %s", pgsql_session_get_error(cursor->session) ); gsql_message_add (workspace, GSQL_MESSAGE_ERROR, error_str); return GSQL_CURSOR_STATE_ERROR; } for (n = 0; n < n_fields; n++) { // where to free this?!? field = g_malloc0 ( sizeof(PGSQL_FIELD) ); field->name = PQfname(e_cursor->result, n); field->type = PQftype(e_cursor->result, n); field->size = PQfsize(e_cursor->result, n); var = gsql_variable_new (); pgsql_variable_init (var, field); cursor->var_list = g_list_append (cursor->var_list, var); } return GSQL_CURSOR_STATE_OPEN; }
/********************************** * pg_result get information about the results of a query syntax: pg_result result ?option? the options are: -status the status of the result -error the error message, if the status indicates error; otherwise an empty string -conn the connection that produced the result -oid if command was an INSERT, the OID of the inserted tuple -numTuples the number of tuples in the query -cmdTuples the number of tuples affected by the query -numAttrs returns the number of attributes returned by the query -assign arrayName assign the results to an array, using subscripts of the form (tupno,attributeName) -assignbyidx arrayName ?appendstr? assign the results to an array using the first field's value as a key. All but the first field of each tuple are stored, using subscripts of the form (field0value,attributeNameappendstr) -getTuple tupleNumber returns the values of the tuple in a list -tupleArray tupleNumber arrayName stores the values of the tuple in array arrayName, indexed by the attributes returned -attributes returns a list of the name/type pairs of the tuple attributes -lAttributes returns a list of the {name type len} entries of the tuple attributes -clear clear the result buffer. Do not reuse after this **********************************/ int Pg_result(ClientData cData, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { PGresult *result; const char *opt; int i; int tupno; CONST84 char *arrVar; char nameBuffer[256]; const char *appendstr; if (argc < 3 || argc > 5) { Tcl_AppendResult(interp, "Wrong # of arguments\n", 0); goto Pg_result_errReturn; /* append help info */ } result = PgGetResultId(interp, argv[1]); if (result == (PGresult *) NULL) { Tcl_AppendResult(interp, "\n", argv[1], " is not a valid query result", 0); return TCL_ERROR; } opt = argv[2]; if (strcmp(opt, "-status") == 0) { Tcl_AppendResult(interp, PQresStatus(PQresultStatus(result)), 0); return TCL_OK; } else if (strcmp(opt, "-error") == 0) { Tcl_SetResult(interp, (char *) PQresultErrorMessage(result), TCL_STATIC); return TCL_OK; } else if (strcmp(opt, "-conn") == 0) return PgGetConnByResultId(interp, argv[1]); else if (strcmp(opt, "-oid") == 0) { sprintf(interp->result, "%u", PQoidValue(result)); return TCL_OK; } else if (strcmp(opt, "-clear") == 0) { PgDelResultId(interp, argv[1]); PQclear(result); return TCL_OK; } else if (strcmp(opt, "-numTuples") == 0) { sprintf(interp->result, "%d", PQntuples(result)); return TCL_OK; } else if (strcmp(opt, "-cmdTuples") == 0) { sprintf(interp->result, "%s", PQcmdTuples(result)); return TCL_OK; } else if (strcmp(opt, "-numAttrs") == 0) { sprintf(interp->result, "%d", PQnfields(result)); return TCL_OK; } else if (strcmp(opt, "-assign") == 0) { if (argc != 4) { Tcl_AppendResult(interp, "-assign option must be followed by a variable name", 0); return TCL_ERROR; } arrVar = argv[3]; /* * this assignment assigns the table of result tuples into a giant * array with the name given in the argument. The indices of the * array are of the form (tupno,attrName). Note we expect field * names not to exceed a few dozen characters, so truncating to * prevent buffer overflow shouldn't be a problem. */ for (tupno = 0; tupno < PQntuples(result); tupno++) { for (i = 0; i < PQnfields(result); i++) { sprintf(nameBuffer, "%d,%.200s", tupno, PQfname(result, i)); if (Tcl_SetVar2(interp, arrVar, nameBuffer, #ifdef TCL_ARRAYS tcl_value(PQgetvalue(result, tupno, i)), #else PQgetvalue(result, tupno, i), #endif TCL_LEAVE_ERR_MSG) == NULL) return TCL_ERROR; } } Tcl_AppendResult(interp, arrVar, 0); return TCL_OK; } else if (strcmp(opt, "-assignbyidx") == 0) { if (argc != 4 && argc != 5) { Tcl_AppendResult(interp, "-assignbyidx option requires an array name and optionally an append string", 0); return TCL_ERROR; } arrVar = argv[3]; appendstr = (argc == 5) ? (const char *) argv[4] : ""; /* * this assignment assigns the table of result tuples into a giant * array with the name given in the argument. The indices of the * array are of the form (field0Value,attrNameappendstr). Here, we * still assume PQfname won't exceed 200 characters, but we dare * not make the same assumption about the data in field 0 nor the * append string. */ for (tupno = 0; tupno < PQntuples(result); tupno++) { const char *field0 = #ifdef TCL_ARRAYS tcl_value(PQgetvalue(result, tupno, 0)); #else PQgetvalue(result, tupno, 0); #endif char *workspace = malloc(strlen(field0) + strlen(appendstr) + 210); for (i = 1; i < PQnfields(result); i++) { sprintf(workspace, "%s,%.200s%s", field0, PQfname(result, i), appendstr); if (Tcl_SetVar2(interp, arrVar, workspace, #ifdef TCL_ARRAYS tcl_value(PQgetvalue(result, tupno, i)), #else PQgetvalue(result, tupno, i), #endif TCL_LEAVE_ERR_MSG) == NULL) { free(workspace); return TCL_ERROR; } } free(workspace); } Tcl_AppendResult(interp, arrVar, 0); return TCL_OK; } else if (strcmp(opt, "-getTuple") == 0) { if (argc != 4) { Tcl_AppendResult(interp, "-getTuple option must be followed by a tuple number", 0); return TCL_ERROR; } tupno = atoi(argv[3]); if (tupno < 0 || tupno >= PQntuples(result)) { Tcl_AppendResult(interp, "argument to getTuple cannot exceed number of tuples - 1", 0); return TCL_ERROR; } #ifdef TCL_ARRAYS for (i = 0; i < PQnfields(result); i++) Tcl_AppendElement(interp, tcl_value(PQgetvalue(result, tupno, i))); #else for (i = 0; i < PQnfields(result); i++) Tcl_AppendElement(interp, PQgetvalue(result, tupno, i)); #endif return TCL_OK; } else if (strcmp(opt, "-tupleArray") == 0) { if (argc != 5) { Tcl_AppendResult(interp, "-tupleArray option must be followed by a tuple number and array name", 0); return TCL_ERROR; } tupno = atoi(argv[3]); if (tupno < 0 || tupno >= PQntuples(result)) { Tcl_AppendResult(interp, "argument to tupleArray cannot exceed number of tuples - 1", 0); return TCL_ERROR; } for (i = 0; i < PQnfields(result); i++) { if (Tcl_SetVar2(interp, argv[4], PQfname(result, i), #ifdef TCL_ARRAYS tcl_value(PQgetvalue(result, tupno, i)), #else PQgetvalue(result, tupno, i), #endif TCL_LEAVE_ERR_MSG) == NULL) return TCL_ERROR; } return TCL_OK; } else if (strcmp(opt, "-attributes") == 0) { for (i = 0; i < PQnfields(result); i++) Tcl_AppendElement(interp, PQfname(result, i)); return TCL_OK; } else if (strcmp(opt, "-lAttributes") == 0) { for (i = 0; i < PQnfields(result); i++) { /* start a sublist */ if (i > 0) Tcl_AppendResult(interp, " {", 0); else Tcl_AppendResult(interp, "{", 0); Tcl_AppendElement(interp, PQfname(result, i)); sprintf(nameBuffer, "%ld", (long) PQftype(result, i)); Tcl_AppendElement(interp, nameBuffer); sprintf(nameBuffer, "%ld", (long) PQfsize(result, i)); Tcl_AppendElement(interp, nameBuffer); /* end the sublist */ Tcl_AppendResult(interp, "}", 0); } return TCL_OK; } else { Tcl_AppendResult(interp, "Invalid option\n", 0); goto Pg_result_errReturn; /* append help info */ } Pg_result_errReturn: Tcl_AppendResult(interp, "pg_result result ?option? where option is\n", "\t-status\n", "\t-error\n", "\t-conn\n", "\t-oid\n", "\t-numTuples\n", "\t-cmdTuples\n", "\t-numAttrs\n" "\t-assign arrayVarName\n", "\t-assignbyidx arrayVarName ?appendstr?\n", "\t-getTuple tupleNumber\n", "\t-tupleArray tupleNumber arrayVarName\n", "\t-attributes\n" "\t-lAttributes\n" "\t-clear\n", (char *) 0); return TCL_ERROR; }
int get_column_info(PGresult * res, int col, int *pgtype, int *gpgtype, int *sqltype, int *size) { *pgtype = (int)PQftype(res, col); *gpgtype = get_gpg_type(*pgtype); /* Convert internal type to PG_TYPE_* */ /* TODO: we should load field names from pg_type table instead of using copy of #defines */ switch (*gpgtype) { case PG_TYPE_BIT: case PG_TYPE_INT2: case PG_TYPE_INT4: case PG_TYPE_INT8: case PG_TYPE_SERIAL: case PG_TYPE_OID: *sqltype = DB_SQL_TYPE_INTEGER; *size = PQfsize(res, col); break; case PG_TYPE_CHAR: case PG_TYPE_BPCHAR: case PG_TYPE_VARCHAR: *sqltype = DB_SQL_TYPE_CHARACTER; *size = PQfmod(res, col) - 4; /* Looks strange but works, something better? */ break; case PG_TYPE_TEXT: *sqltype = DB_SQL_TYPE_TEXT; break; case PG_TYPE_FLOAT4: case PG_TYPE_FLOAT8: case PG_TYPE_NUMERIC: *sqltype = DB_SQL_TYPE_DOUBLE_PRECISION; *size = PQfsize(res, col); break; /* I'm not sure if text length is correct for size */ case PG_TYPE_DATE: *sqltype = DB_SQL_TYPE_DATE; *size = 10; /* YYYY-MM-DD */ break; case PG_TYPE_TIME: *sqltype = DB_SQL_TYPE_TIME; *size = 8; /* HH:MM:SS */ break; case PG_TYPE_TIMESTAMP: *sqltype = DB_SQL_TYPE_TIMESTAMP; *size = 22; /* YYYY-MM-DD HH:MM:SS+TZ */ break; case PG_TYPE_BOOL: *sqltype = DB_SQL_TYPE_CHARACTER; *size = 1; break; default: *sqltype = DB_SQL_TYPE_UNKNOWN; *size = 0; } return 0; }
size_t DTTablePostgres::columnDataSize(int columnNumber) const { //returns -1 for varchar if (columnNumber >= columnCount() || columnNumber < 0) { EXToutOfRange("Column number is out of range"); } return (size_t) PQfsize(result, columnNumber); }
static HB_ERRCODE pgsqlOpen( SQLBASEAREAP pArea ) { PGconn * pConn = ( ( SDDCONN * ) pArea->pConnection->pSDDConn )->pConn; SDDDATA * pSDDData; PGresult * pResult; ExecStatusType status; PHB_ITEM pItemEof, pItem; HB_USHORT uiFields, uiCount; HB_BOOL bError; DBFIELDINFO pFieldInfo; pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) ); pSDDData = ( SDDDATA * ) pArea->pSDDData; pResult = PQexec( pConn, pArea->szQuery ); if( ! pResult ) { hb_errRT_PostgreSQLDD( EG_OPEN, ESQLDD_LOWMEMORY, "Query failed", NULL, 0 ); /* Low memory, etc */ return HB_FAILURE; } status = PQresultStatus( pResult ); if( status != PGRES_TUPLES_OK && status != PGRES_COMMAND_OK ) { hb_errRT_PostgreSQLDD( EG_OPEN, ESQLDD_INVALIDQUERY, PQresultErrorMessage( pResult ), pArea->szQuery, ( HB_ERRCODE ) status ); PQclear( pResult ); return HB_FAILURE; } pSDDData->pResult = pResult; uiFields = ( HB_USHORT ) PQnfields( pResult ); SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); pItemEof = hb_itemArrayNew( uiFields ); pItem = hb_itemNew( NULL ); bError = HB_FALSE; for( uiCount = 0; uiCount < uiFields; uiCount++ ) { pFieldInfo.atomName = PQfname( pResult, ( int ) uiCount ); pFieldInfo.uiDec = 0; switch( PQftype( pResult, ( int ) uiCount ) ) { case BPCHAROID: case VARCHAROID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = ( HB_USHORT ) PQfmod( pResult, uiCount ) - 4; break; case TEXTOID: pFieldInfo.uiType = HB_FT_MEMO; pFieldInfo.uiLen = 10; break; case NUMERICOID: pFieldInfo.uiType = HB_FT_DOUBLE; pFieldInfo.uiLen = ( PQfmod( pResult, uiCount ) - 4 ) >> 16; pFieldInfo.uiDec = ( PQfmod( pResult, uiCount ) - 4 ) & 0xFFFF; break; case INT2OID: pFieldInfo.uiType = HB_FT_INTEGER; pFieldInfo.uiLen = 6; break; case INT4OID: pFieldInfo.uiType = HB_FT_INTEGER; pFieldInfo.uiLen = 11; break; case INT8OID: case OIDOID: pFieldInfo.uiType = HB_FT_LONG; pFieldInfo.uiLen = 20; break; case FLOAT4OID: case FLOAT8OID: case CASHOID: /* TODO: ??? */ pFieldInfo.uiType = HB_FT_DOUBLE; pFieldInfo.uiLen = 16; pFieldInfo.uiDec = 2; /* TODO: hb_set.SET_DECIMALS ??? */ break; case BOOLOID: pFieldInfo.uiType = HB_FT_LOGICAL; pFieldInfo.uiLen = 1; break; case DATEOID: pFieldInfo.uiType = HB_FT_DATE; pFieldInfo.uiLen = 8; break; case INETOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 29; break; case CIDROID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 32; break; case MACADDROID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 17; break; case BITOID: case VARBITOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = ( HB_USHORT ) PQfsize( pResult, uiCount ); break; case TIMEOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 12; break; case TIMESTAMPOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 23; break; case TIMETZOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 15; break; case TIMESTAMPTZOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 26; break; case NAMEOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 63; break; case BYTEAOID: pFieldInfo.uiType = HB_FT_STRING; pFieldInfo.uiLen = 0; break; default: pFieldInfo.uiType = 0; pFieldInfo.uiLen = 0; bError = HB_TRUE; break; } /* printf( "field:%s \ttype:%d \tsize:%d \tformat:%d \tmod:%d err=%d\n", pFieldInfo.atomName, PQftype( pResult, ( int ) uiCount ), PQfsize( pResult, uiCount ), PQfformat( pResult, uiCount ) , PQfmod( pResult, uiCount ), bError ); */ if( ! bError ) { switch( pFieldInfo.uiType ) { case HB_FT_STRING: { char * pStr; pStr = ( char * ) hb_xgrab( pFieldInfo.uiLen + 1 ); memset( pStr, ' ', pFieldInfo.uiLen ); pStr[ pFieldInfo.uiLen ] = '\0'; hb_itemPutCL( pItem, pStr, pFieldInfo.uiLen ); hb_xfree( pStr ); break; } case HB_FT_MEMO: hb_itemPutC( pItem, NULL ); hb_itemSetCMemo( pItem ); break; case HB_FT_INTEGER: hb_itemPutNI( pItem, 0 ); break; case HB_FT_LONG: hb_itemPutNL( pItem, 0 ); break; case HB_FT_DOUBLE: hb_itemPutND( pItem, 0.0 ); break; case HB_FT_LOGICAL: hb_itemPutL( pItem, HB_FALSE ); break; case HB_FT_DATE: hb_itemPutDS( pItem, NULL ); break; default: hb_itemClear( pItem ); bError = HB_TRUE; break; } hb_arraySetForward( pItemEof, uiCount + 1, pItem ); /* if( pFieldInfo.uiType == HB_IT_DOUBLE || pFieldInfo.uiType == HB_IT_INTEGER ) pFieldInfo.uiType = HB_IT_LONG; */ if( ! bError ) bError = ( SELF_ADDFIELD( ( AREAP ) pArea, &pFieldInfo ) == HB_FAILURE ); } if( bError ) break; } hb_itemRelease( pItem ); if( bError ) { hb_itemClear( pItemEof ); hb_itemRelease( pItemEof ); hb_errRT_PostgreSQLDD( EG_CORRUPTION, ESQLDD_INVALIDFIELD, "Invalid field type", pArea->szQuery, 0 ); return HB_FAILURE; } pArea->ulRecCount = ( HB_ULONG ) PQntuples( pResult ); pArea->pRow = ( void ** ) hb_xgrab( ( pArea->ulRecCount + 1 ) * sizeof( void * ) ); pArea->pRowFlags = ( HB_BYTE * ) hb_xgrab( ( pArea->ulRecCount + 1 ) * sizeof( HB_BYTE ) ); memset( pArea->pRowFlags, 0, ( pArea->ulRecCount + 1 ) * sizeof( HB_BYTE ) ); *pArea->pRow = pItemEof; pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED; pArea->fFetched = HB_TRUE; return HB_SUCCESS; }
/** * Obtain a random key-value pair from the datacache. * * @param cls closure (our `struct Plugin`) * @param iter maybe NULL (to just count) * @param iter_cls closure for @a iter * @return the number of results found, zero (datacache empty) or one */ static unsigned int postgres_plugin_get_random (void *cls, GNUNET_DATACACHE_Iterator iter, void *iter_cls) { struct Plugin *plugin = cls; unsigned int off; uint32_t off_be; struct GNUNET_TIME_Absolute expiration_time; uint32_t size; unsigned int path_len; const struct GNUNET_PeerIdentity *path; const struct GNUNET_HashCode *key; unsigned int type; PGresult *res; const char *paramValues[] = { (const char *) &off_be }; int paramLengths[] = { sizeof (off_be) }; const int paramFormats[] = { 1 }; if (0 == plugin->num_items) return 0; if (NULL == iter) return 1; off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, plugin->num_items); off_be = htonl (off); res = PQexecPrepared (plugin->dbh, "get_random", 1, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", "get_random")) { GNUNET_break (0); return 0; } if (0 == PQntuples (res)) { GNUNET_break (0); return 0; } if ( (5 != PQnfields (res)) || (sizeof (uint64_t) != PQfsize (res, 0)) || (sizeof (uint32_t) != PQfsize (res, 1)) || (sizeof (struct GNUNET_HashCode) != PQfsize (res, 4)) ) { GNUNET_break (0); PQclear (res); return 0; } expiration_time.abs_value_us = GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, 0, 0)); type = ntohl (*(uint32_t *) PQgetvalue (res, 0, 1)); size = PQgetlength (res, 0, 2); path_len = PQgetlength (res, 0, 3); if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity))) { GNUNET_break (0); path_len = 0; } path_len %= sizeof (struct GNUNET_PeerIdentity); path = (const struct GNUNET_PeerIdentity *) PQgetvalue (res, 0, 3); key = (const struct GNUNET_HashCode *) PQgetvalue (res, 0, 4); LOG (GNUNET_ERROR_TYPE_DEBUG, "Found random value with key %s of size %u bytes and type %u in database\n", GNUNET_h2s (key), (unsigned int) size, (unsigned int) type); (void) iter (iter_cls, key, size, PQgetvalue (res, 0, 2), (enum GNUNET_BLOCK_Type) type, expiration_time, path_len, path); PQclear (res); return 1; }
/** * Iterate over the results that are "close" to a particular key in * the datacache. "close" is defined as numerically larger than @a * key (when interpreted as a circular address space), with small * distance. * * @param cls closure (internal context for the plugin) * @param key area of the keyspace to look into * @param num_results number of results that should be returned to @a iter * @param iter maybe NULL (to just count) * @param iter_cls closure for @a iter * @return the number of results found */ static unsigned int postgres_plugin_get_closest (void *cls, const struct GNUNET_HashCode *key, unsigned int num_results, GNUNET_DATACACHE_Iterator iter, void *iter_cls) { struct Plugin *plugin = cls; uint32_t nbo_limit = htonl (num_results); const char *paramValues[] = { (const char *) key, (const char *) &nbo_limit, }; int paramLengths[] = { sizeof (struct GNUNET_HashCode), sizeof (nbo_limit) }; const int paramFormats[] = { 1, 1 }; struct GNUNET_TIME_Absolute expiration_time; uint32_t size; unsigned int type; unsigned int cnt; unsigned int i; unsigned int path_len; const struct GNUNET_PeerIdentity *path; PGresult *res; res = PQexecPrepared (plugin->dbh, "get_closest", 2, paramValues, paramLengths, paramFormats, 1); if (GNUNET_OK != GNUNET_POSTGRES_check_result (plugin->dbh, res, PGRES_TUPLES_OK, "PQexecPrepared", "get_closest")) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Ending iteration (postgres error)\n"); return 0; } if (0 == (cnt = PQntuples (res))) { /* no result */ LOG (GNUNET_ERROR_TYPE_DEBUG, "Ending iteration (no more results)\n"); PQclear (res); return 0; } if (NULL == iter) { PQclear (res); return cnt; } if ( (5 != PQnfields (res)) || (sizeof (uint64_t) != PQfsize (res, 0)) || (sizeof (uint32_t) != PQfsize (res, 1)) || (sizeof (struct GNUNET_HashCode) != PQfsize (res, 4)) ) { GNUNET_break (0); PQclear (res); return 0; } for (i = 0; i < cnt; i++) { expiration_time.abs_value_us = GNUNET_ntohll (*(uint64_t *) PQgetvalue (res, i, 0)); type = ntohl (*(uint32_t *) PQgetvalue (res, i, 1)); size = PQgetlength (res, i, 2); path_len = PQgetlength (res, i, 3); if (0 != (path_len % sizeof (struct GNUNET_PeerIdentity))) { GNUNET_break (0); path_len = 0; } path_len %= sizeof (struct GNUNET_PeerIdentity); path = (const struct GNUNET_PeerIdentity *) PQgetvalue (res, i, 3); key = (const struct GNUNET_HashCode *) PQgetvalue (res, i, 4); LOG (GNUNET_ERROR_TYPE_DEBUG, "Found result of size %u bytes and type %u in database\n", (unsigned int) size, (unsigned int) type); if (GNUNET_SYSERR == iter (iter_cls, key, size, PQgetvalue (res, i, 2), (enum GNUNET_BLOCK_Type) type, expiration_time, path_len, path)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Ending iteration (client error)\n"); PQclear (res); return cnt; } } PQclear (res); return cnt; }
RS_DBI_fields * RS_PostgreSQL_createDataMappings(Res_Handle * rsHandle) { PGresult *my_result; RS_DBI_connection *con; RS_DBI_resultSet *result; RS_DBI_fields *flds; int j, num_fields, internal_type; char errMsg[128]; result = RS_DBI_getResultSet(rsHandle); my_result = (PGresult *) result->drvResultSet; con = RS_DBI_getConnection(rsHandle); num_fields = PQnfields(my_result); flds = RS_DBI_allocFields(num_fields); /* this returns malloced data (not from R) */ char buff[1000]; /* Buffer to hold the sql query to check whether the given column is nullable */ PGconn *conn; PGresult *res; conn = (PGconn *) con->drvConnection; for (j = 0; j < num_fields; j++) { flds->name[j] = RS_DBI_copyString(PQfname(my_result, j)); flds->type[j] = (int) PQftype(my_result, j); flds->length[j] = (Sint) PQfsize(my_result, j); /* NOTE: PQfmod is -1 incase of no information */ flds->precision[j] = (Sint) PQfmod(my_result, j); flds->scale[j] = (Sint) - 1; /* PQftablecol returns the column number (within its table) of * the column making up the specified query result column.Zero * is returned if the column number is out of range, or if the * specified column is not a simple reference to a table * column, or when using pre-3.0 protocol. So * "if(PQftablecol(my_result,j) !=0)" checks whether the * particular colomn in the result set is column of table or * not. Or else there is no meaning in checking whether a * column is nullable or not if it does not belong to the * table. */ flds->nullOk[j] = (Sint) INT_MIN; /* This should translate to NA in R */ if (PQftablecol(my_result, j) != 0) { /* Code to find whether a row can be nullable or not */ /* we might better just store the table id and column number for lazy evaluation at dbColumnInfo call*/ /* although the database structure can change, we are not in transaction anyway and there is no guarantee in current code */ snprintf(buff, 1000, "select attnotnull from pg_attribute where attrelid=%d and attnum='%d'", PQftable(my_result, j), PQftablecol(my_result, j)); res = PQexec(conn, buff); if (res && (PQntuples(res) > 0)) { const char * attnotnull = PQgetvalue(res, 0, 0); if(strcmp(attnotnull, "f") == 0) { flds->nullOk[j] = (Sint) 1; /* nollOK is TRUE when attnotnull is f*/ } if(strcmp(attnotnull, "t") == 0) { flds->nullOk[j] = (Sint) 0; /* nollOK is FALSE when attnotnull is t*/ } } PQclear(res); } internal_type = (int) PQftype(my_result, j); switch (internal_type) { case BOOLOID: flds->Sclass[j] = LOGICAL_TYPE; break; case BPCHAROID: flds->Sclass[j] = CHARACTER_TYPE; flds->isVarLength[j] = (Sint) 0; break; case VARCHAROID: case TEXTOID: case BYTEAOID: case NAMEOID: case MACADDROID: case INETOID: flds->Sclass[j] = CHARACTER_TYPE; flds->isVarLength[j] = (Sint) 1; break; case INT2OID: case INT4OID: case OIDOID: flds->Sclass[j] = INTEGER_TYPE; break; case INT8OID: if (sizeof(Sint) >= 8) { flds->Sclass[j] = INTEGER_TYPE; } else { flds->Sclass[j] = NUMERIC_TYPE; } break; case NUMERICOID: case FLOAT8OID: case FLOAT4OID: flds->Sclass[j] = NUMERIC_TYPE; break; case DATEOID: case TIMEOID: case TIMETZOID: case TIMESTAMPOID: case TIMESTAMPTZOID: case INTERVALOID: flds->Sclass[j] = CHARACTER_TYPE; /*flds->isVarLength[j] = (Sint) 1; */ break; default: flds->Sclass[j] = CHARACTER_TYPE; flds->isVarLength[j] = (Sint) 1; snprintf(buff, 1000, "select typname, typcategory from pg_type where oid = %d", internal_type); res = PQexec(conn, buff); if (res) { char * typename; char * typecat; int ntuples; ntuples = PQntuples(res); if(ntuples == 1) { typename = PQgetvalue(res, 0, 0); typecat = PQgetvalue(res, 0, 1); if(*typecat == 'E') { /* This is enum, ok */ } else if(*typecat == 'A') { /*This is array, ok */ } else { snprintf(errMsg, 128, "unrecognized PostgreSQL field type %s (id:%d) in column %d", typename, internal_type, j); RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } } else { snprintf(errMsg, 128, "oid: %d, ntuples: %d", internal_type, ntuples); RS_DBI_errorMessage(errMsg, RS_DBI_WARNING); } PQclear(res); } else {
/* --------------------------------------------------------------------- * PgResultColumnSize * Field size in the specified column * --------------------------------------------------------------------- */ int PgResultColumnSize(SQLRESULT* result, int index) { return PQfsize(result->Result, index); }
GSQLCursorState pgsql_cursor_open_bind (GSQLCursor *cursor, GList *args) { GSQL_TRACE_FUNC; GSQLEPGSQLSession *e_session = NULL; GSQLEPGSQLCursor *e_cursor = NULL; GSQLVariable *var; GSQLWorkspace *workspace = NULL; PGSQL_FIELD *field; gulong binds_arg, n, n_fields, is_null = 1; // store parameters information Oid *paramTypes = NULL; const char **paramValues = NULL; int *paramLengths = NULL; int *paramFormats = NULL; GList *vlist = args; GType vtype; gchar error_str[2048]; g_return_if_fail (GSQL_IS_CURSOR(cursor)); g_return_if_fail(GSQL_IS_SESSION(cursor->session)); e_session = cursor->session->spec; workspace = gsql_session_get_workspace (cursor->session); g_return_if_fail(GSQL_IS_WORKSPACE(workspace)); if (!pgsql_cursor_prepare (cursor)) { return GSQL_CURSOR_STATE_ERROR; } e_cursor = cursor->spec; binds_arg = g_list_length (args) / 2; paramTypes = g_malloc0 ( sizeof(Oid) * binds_arg ); paramValues = g_malloc0 ( sizeof (char *) * binds_arg ); paramLengths = g_malloc0 ( sizeof(int) * binds_arg ); paramFormats = g_malloc0 ( sizeof(int) * binds_arg ); n = 0; GSQL_DEBUG ( "Executing [%s]...", cursor->sql ); while (vlist) { vtype = (GType) vlist->data; vlist = g_list_next (vlist); if (vlist->data == NULL) is_null = 1; else is_null = 0; switch (vtype) { case G_TYPE_STRING: case G_TYPE_POINTER: paramTypes[n] = VARCHAROID; paramValues[n] = (char *) vlist->data; paramLengths[n] = g_utf8_strlen((gchar *) vlist->data, 1048576); paramFormats[n] = 0; break; case G_TYPE_INT: case G_TYPE_UINT: paramTypes[n] = INT4OID; paramValues[n] = (char *) &vlist->data; paramLengths[n] = 0; paramFormats[n] = 0; break; case G_TYPE_UINT64: case G_TYPE_INT64: paramTypes[n] = INT8OID; paramValues[n] = (char *) &vlist->data; paramLengths[n] = 0; paramFormats[n] = 0; break; case G_TYPE_DOUBLE: paramTypes[n] = FLOAT4OID; paramValues[n] = (char *) &vlist->data; paramLengths[n] = 0; paramFormats[n] = 0; break; } //GSQL_DEBUG ("Parms [%d] = [%s]", n, paramValues[n]); vlist = g_list_next (vlist); n++; } if (! e_session->pgconn ) { GSQL_DEBUG ("BIND: pgconn empty!"); } if ( PQstatus(e_session->pgconn) != CONNECTION_OK ) { GSQL_DEBUG("BIND: lost connection!"); } e_cursor->result = PQexecParams(e_session->pgconn, cursor->sql, binds_arg, paramTypes, paramValues, paramLengths, paramFormats, 0); if ( ! e_cursor->result ) { g_sprintf ( error_str, "Error occured: %s", pgsql_session_get_error(cursor->session) ); gsql_message_add (workspace, GSQL_MESSAGE_ERROR, error_str); g_free (paramTypes); g_free (paramValues); g_free (paramLengths); g_free (paramFormats); return GSQL_CURSOR_STATE_ERROR; } pgsql_cursor_statement_detect (cursor); g_free (paramTypes); g_free (paramValues); g_free (paramLengths); g_free (paramFormats); n_fields = PQnfields (e_cursor->result); if (n_fields == 0) return GSQL_CURSOR_STATE_OPEN; for (n = 0; n < n_fields; n++) { // TODO: free this in on_variable_delete field = g_malloc0 ( sizeof(PGSQL_FIELD) ); field->name = PQfname(e_cursor->result, n); field->type = PQftype(e_cursor->result, n); field->size = PQfsize(e_cursor->result, n); var = gsql_variable_new (); pgsql_variable_init (var, field); cursor->var_list = g_list_append (cursor->var_list, var); } return GSQL_CURSOR_STATE_OPEN; }
int pg_createrowset(ClipMachine* mp,SQLROWSET* rs,ClipVar* ap,ClipVar* idname,const char* gen_idSQL){ PG_ROWSET* rowset = (PG_ROWSET*)rs; PG_STMT* stmt = rowset->stmt; PG_CONN* conn = rowset->conn; int i,mod; pg_bindpars(stmt,ap); if(!stmt->sql){ _clip_trap_err(mp,0,0,0,subsys,ER_NOSQL,er_nosql); return 1; } stmt->res = PQexec(conn->conn,stmt->sql); if(!stmt->res){ _clip_trap_err(mp,0,0,0,subsys,ER_BADSTATEMENT, PQresultErrorMessage(stmt->res)); return 1; } if(PQresultStatus(stmt->res)!=PGRES_TUPLES_OK){ _clip_trap_err(mp,0,0,0,subsys,ER_BADSELECT, PQresultErrorMessage(stmt->res)); return 1; } rowset->rowset_item = _clip_store_c_item(mp,rowset,_C_ITEM_TYPE_SQL,destroy_pg_rowset); rowset->binary = PQbinaryTuples(stmt->res); rowset->nfields = PQnfields(stmt->res); rowset->fields = calloc(1,rowset->nfields*sizeof(SQLFIELD)); rowset->id = -1; for(i=0;i<rowset->nfields;i++){ strncpy(rowset->fields[i].name,PQfname(stmt->res,i), MAXFIELDNAME); rowset->fields[i].name[MAXFIELDNAME] = 0; rowset->fields[i].type = PQftype(stmt->res,i); rowset->fields[i].ctype[0] = _pg_ctype(rowset->fields[i].type); rowset->fields[i].dec = 0; mod = PQfmod(stmt->res,i); switch(rowset->fields[i].type){ case PGT_BPCHAR: case PGT_CHAR: case PGT_VARCHAR: rowset->fields[i].len = mod-4; break; case PGT_TEXT: rowset->fields[i].len = 10; break; case PGT_NUMERIC: rowset->fields[i].len = (mod >> 16); rowset->fields[i].dec = (mod & 0xffff)-4; break; case PGT_DATE: rowset->fields[i].len = 8; break; default: rowset->fields[i].len = PQfsize(stmt->res,i); break; } rowset->fields[i].ops = 0; if(idname && idname->t.type == CHARACTER_t && idname->s.str.buf){ if(!strcasecmp(rowset->fields[i].name,idname->s.str.buf)){ rowset->id = i; } } else if(rowset->fields[i].type == PGT_OID){ rowset->id = i; } } rowset->lastrec = PQntuples(stmt->res); rowset->data = calloc(rowset->lastrec,sizeof(void*)); return 0; }