void __table_log_restore_table_update(SPITupleTable *spi_tuptable, char *table_restore, char *table_orig_pkey, char *col_query_start, int col_pkey, int number_columns, int i, char *old_pkey_string) { int size_of_values, j, ret; char *tmp, *tmp2; /* memory for dynamic query */ int d_query_size; char *d_query; char *d_query_start; /* get the size of names and values */ size_of_values = 0; /* go through all columns in this result */ for (j = 1; j <= number_columns; j++) { /* get value */ tmp = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, j); /* and get name of column */ tmp2 = SPI_fname(spi_tuptable->tupdesc, j); if (tmp == NULL) { size_of_values += 6 + strlen(do_quote_ident(tmp2)) + 2; } else { size_of_values += strlen(do_quote_literal(tmp)) + strlen(do_quote_ident(tmp2)) + 3; } } /* reserve memory */ d_query_size = 250 + size_of_values + NAMEDATALEN + strlen(do_quote_literal(old_pkey_string)); d_query_start = (char *) palloc((d_query_size + 1) * sizeof(char)); d_query = d_query_start; /* build query */ sprintf(d_query, "UPDATE %s SET ", do_quote_ident(table_restore)); d_query = d_query_start + strlen(d_query_start); for (j = 1; j <= number_columns; j++) { if (j > 1) { strncat(d_query_start, (const char *)", ", d_query_size); d_query += 2; } tmp = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, j); tmp2 = SPI_fname(spi_tuptable->tupdesc, j); if (tmp == NULL) { snprintf(d_query, d_query_size, "%s=NULL", do_quote_ident(tmp2)); } else { snprintf(d_query, d_query_size, "%s=%s", do_quote_ident(tmp2), do_quote_literal(tmp)); } d_query = d_query_start + strlen(d_query_start); } snprintf(d_query, d_query_size, " WHERE %s=%s", do_quote_ident(table_orig_pkey), do_quote_literal(old_pkey_string)); d_query = d_query_start + strlen(d_query_start); #ifdef TABLE_LOG_DEBUG_QUERY elog(NOTICE, "query: %s", d_query_start); #endif /* TABLE_LOG_DEBUG_QUERY */ ret = SPI_exec(d_query_start, 0); if (ret != SPI_OK_UPDATE) { elog(ERROR, "could not update data in: %s", table_restore); } /* done */ }
void __table_log_restore_table_insert(SPITupleTable *spi_tuptable, char *table_restore, char *table_orig_pkey, char *col_query_start, int col_pkey, int number_columns, int i) { int size_of_values, j, ret; char *tmp; /* memory for dynamic query */ int d_query_size; char *d_query; char *d_query_start; /* get the size of values */ size_of_values = 0; /* go through all columns in this result */ for (j = 1; j <= number_columns; j++) { tmp = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, j); if (tmp == NULL) { size_of_values += 6; } else { size_of_values += strlen(do_quote_literal(tmp)) + 3; } } /* reserve memory */ d_query_size = 250 + strlen(col_query_start) + size_of_values; d_query_start = (char *) palloc((d_query_size + 1) * sizeof(char)); d_query = d_query_start; /* build query */ sprintf(d_query, "INSERT INTO %s (%s) VALUES (", do_quote_ident(table_restore), col_query_start); d_query = d_query_start + strlen(d_query_start); for (j = 1; j <= number_columns; j++) { if (j > 1) { strncat(d_query_start, (const char *)", ", d_query_size); } tmp = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, j); if (tmp == NULL) { strncat(d_query_start, (const char *)"NULL", d_query_size); } else { strncat(d_query_start, do_quote_literal(tmp), d_query_size); } } strncat(d_query_start, (const char *)")", d_query_size); #ifdef TABLE_LOG_DEBUG_QUERY elog(NOTICE, "query: %s", d_query_start); #endif /* TABLE_LOG_DEBUG_QUERY */ ret = SPI_exec(d_query_start, 0); if (ret != SPI_OK_INSERT) { elog(ERROR, "could not insert data into: %s", table_restore); } /* done */ }
char *lookup_primary_key(char *schemaName, char *tableName, bool failOnMissing) { StringInfo sql = makeStringInfo(); char *keyname; SPI_connect(); appendStringInfo(sql, "SELECT column_name FROM information_schema.key_column_usage WHERE table_schema = '%s' AND table_name = '%s'", schemaName, tableName); SPI_execute(sql->data, true, 1); if (SPI_processed == 0) { if (failOnMissing) elog(ERROR, "Cannot find primary key column for: %s.%s", schemaName, tableName); else { SPI_finish(); return NULL; } } keyname = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1); if (keyname == NULL) elog(ERROR, "Primary Key field is null for: %s.%s", schemaName, tableName); keyname = MemoryContextStrdup(TopTransactionContext, keyname); SPI_finish(); return keyname; }
static void process_delete(PgqTriggerEvent *ev, StringInfo sql) { TriggerData *tg = ev->tgdata; HeapTuple old_row = tg->tg_trigtuple; TupleDesc tupdesc = tg->tg_relation->rd_att; char *col_ident; char *col_value; int i; int need_and = false; int attkind_idx; for (i = 0, attkind_idx = -1; i < tupdesc->natts; i++) { if (tupdesc->attrs[i]->attisdropped) continue; attkind_idx++; if (!pgqtriga_is_pkey(ev, i, attkind_idx)) continue; col_ident = SPI_fname(tupdesc, i + 1); col_value = SPI_getvalue(old_row, tupdesc, i + 1); if (need_and) appendStringInfoString(sql, " and "); else need_and = true; append_key_eq(sql, col_ident, col_value); } }
/* * Returns a count of the number of non-template databases from the catalog. */ int get_database_count(void) { int retval, processed; StringInfoData buf; SPITupleTable *coltuptable; int database_count = 0; SetCurrentStatementStartTimestamp(); StartTransactionCommand(); SPI_connect(); PushActiveSnapshot(GetTransactionSnapshot()); initStringInfo(&buf); appendStringInfo(&buf, "SELECT count(*) FROM pg_database WHERE datname NOT IN ('template0', 'template1') AND datallowconn IS TRUE;"); retval = SPI_execute(buf.data, false, 0); if (retval != SPI_OK_SELECT) { elog(FATAL, "Database information collection failed"); // FAIL RETURN 1 } processed = SPI_processed; if (processed > 0) { coltuptable = SPI_tuptable; database_count = atoi(SPI_getvalue(coltuptable->vals[0], coltuptable->tupdesc, 1)); } SPI_finish(); PopActiveSnapshot(); CommitTransactionCommand(); return database_count; }
/* * plphp_zval_from_tuple * Build a PHP hash from a tuple. */ zval * plphp_zval_from_tuple(HeapTuple tuple, TupleDesc tupdesc) { int i; char *attname = NULL; zval *array; MAKE_STD_ZVAL(array); array_init(array); for (i = 0; i < tupdesc->natts; i++) { char *attdata; /* Get the attribute name */ attname = tupdesc->attrs[i]->attname.data; /* and get its value */ if ((attdata = SPI_getvalue(tuple, tupdesc, i + 1)) != NULL) { /* "true" means strdup the string */ add_assoc_string(array, attname, attdata, true); pfree(attdata); } else add_assoc_null(array, attname); } return array; }
char * plj_get_configvalue_string(const char *paramName) { char *sql; int proc, ret; /* * no SPI_connect, we are already connected. */ sql = SPI_palloc(strlen(paramName) + strlen(get_sql)); sprintf(sql, get_sql, paramName); ret = SPI_exec(sql, 1); proc = SPI_processed; if (ret == SPI_OK_SELECT && proc > 0) { TupleDesc tupdesc = SPI_tuptable->tupdesc; SPITupleTable *tuptable = SPI_tuptable; return SPI_getvalue(tuptable->vals[0], tupdesc, 1); } elog(WARNING, "[config db] config value not set: %s", paramName); return ""; }
static void fetch_restriction( HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info[4], Restrict_t *restriction) { restriction->id = pgr_SPI_getBigInt(tuple, tupdesc, info[0]); restriction->cost = pgr_SPI_getFloat8(tuple, tupdesc, info[1]); char *str = DatumGetCString( SPI_getvalue(*tuple, *tupdesc, info[2].colNumber)); // TODO(someone) because its text, no guarantee the text read is correct // move this code to c++ to tokenize the integers. int i = 0; for (i = 0; i < MAX_RULE_LENGTH; ++i) restriction->restricted_edges[i] = -1; str[0] = ','; if (str != NULL) { char *token = NULL; int i = 0; token = (char *)strtok(str, " ,"); while (token != NULL && i < MAX_RULE_LENGTH) { restriction->restricted_edges[i] = atoi(token); i++; token = (char *)strtok(NULL, " ,"); } } }
void __table_log_restore_table_delete(SPITupleTable *spi_tuptable, char *table_restore, char *table_orig_pkey, char *col_query_start, int col_pkey, int number_columns, int i) { int ret; char *tmp; /* memory for dynamic query */ int d_query_size; char *d_query; char *d_query_start; /* get the size of value */ tmp = SPI_getvalue(spi_tuptable->vals[i], spi_tuptable->tupdesc, col_pkey); if (tmp == NULL) { elog(ERROR, "pkey cannot be NULL"); } /* reserve memory */ d_query_size = 250 + strlen(do_quote_ident(table_restore)) + strlen(do_quote_ident(table_orig_pkey)) + strlen(do_quote_literal(tmp)); d_query_start = (char *) palloc((d_query_size + 1) * sizeof(char)); d_query = d_query_start; /* build query */ sprintf(d_query, "DELETE FROM %s WHERE %s=%s", do_quote_ident(table_restore), do_quote_ident(table_orig_pkey), do_quote_literal(tmp)); d_query = d_query_start + strlen(d_query_start); #ifdef TABLE_LOG_DEBUG_QUERY elog(NOTICE, "query: %s", d_query_start); #endif /* TABLE_LOG_DEBUG_QUERY */ ret = SPI_exec(d_query_start, 0); if (ret != SPI_OK_DELETE) { elog(ERROR, "could not delete data from: %s", table_restore); } /* done */ }
static void getExtensionLoadPath() { MemoryContext curr; Datum dtm; bool isnull; /* * Check whether sqlj.loadpath exists before querying it. I would more * happily just PG_CATCH() the error and compare to ERRCODE_UNDEFINED_TABLE * but what's required to make that work right is "not terribly well * documented, but the exception-block handling in plpgsql provides a * working model" and that code is a lot more fiddly than you would guess. */ if ( InvalidOid == get_relname_relid("loadpath", GetSysCacheOid1(NAMESPACENAME, CStringGetDatum("sqlj"))) ) return; SPI_connect(); curr = CurrentMemoryContext; if ( SPI_OK_SELECT == SPI_execute( "SELECT path, exnihilo FROM sqlj.loadpath", true, 1) && 1 == SPI_processed ) { MemoryContextSwitchTo(TopMemoryContext); pljavaLoadPath = (char const *)SPI_getvalue( SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1); MemoryContextSwitchTo(curr); dtm = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull); if ( isnull ) elog(ERROR, "defect in CREATE EXTENSION script"); extensionExNihilo = DatumGetBool(dtm); } SPI_finish(); }
struct PlaceSpecification * getPlaceSpecificationFromDatabase(long long placeid) { const char * query = build_placeSpecQuery(placeid); if ( SPI_execute(query, true, 1) != SPI_OK_SELECT ) ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg( "Error when performing placeid query"))); if ( SPI_processed < 1 ) ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg( "unable to find placespecification"))); else if ( SPI_processed > 1 ) ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg( "too many placespecifications returned!"))); HeapTuple placeRow = * SPI_tuptable->vals; struct PlaceSpecification * ret = (struct PlaceSpecification *) malloc(sizeof(struct PlaceSpecification)); ret->startX_ = DatumGetFloat4( SPI_getbinval(placeRow, SPI_tuptable->tupdesc, 1, NULL) ); ret->startY_ = DatumGetFloat4( SPI_getbinval(placeRow, SPI_tuptable->tupdesc, 2, NULL) ); ret->xNumber_ = DatumGetInt32( SPI_getbinval(placeRow, SPI_tuptable->tupdesc, 3, NULL) ); ret->yNumber_ = DatumGetInt32( SPI_getbinval(placeRow, SPI_tuptable->tupdesc, 4, NULL) ); ret->xIncrement_ = DatumGetFloat4( SPI_getbinval(placeRow, SPI_tuptable->tupdesc, 5, NULL) ); ret->yIncrement_ = DatumGetFloat4( SPI_getbinval(placeRow, SPI_tuptable->tupdesc, 6, NULL) ); ret->srid_ = DatumGetInt32( SPI_getbinval(placeRow, SPI_tuptable->tupdesc, 7, NULL) ); char * projDef = SPI_getvalue(placeRow, SPI_tuptable->tupdesc, 8); ret->projDefinition_ = strdup(projDef); pfree(projDef); return ret; }
/* * load queue info from pgq.queue table. */ static void load_queue_info(Datum queue_name, struct QueueState *state) { Datum values[1]; int res; TupleDesc desc; HeapTuple row; bool isnull; values[0] = queue_name; res = SPI_execute_plan(queue_plan, values, NULL, false, 0); if (res != SPI_OK_SELECT) elog(ERROR, "Queue fetch failed"); if (SPI_processed == 0) elog(ERROR, "No such queue"); row = SPI_tuptable->vals[0]; desc = SPI_tuptable->tupdesc; state->queue_id = DatumGetInt32(SPI_getbinval(row, desc, COL_QUEUE_ID, &isnull)); if (isnull) elog(ERROR, "queue id NULL"); state->cur_table = DatumGetInt32(SPI_getbinval(row, desc, COL_TBLNO, &isnull)); if (isnull) elog(ERROR, "table nr NULL"); state->table_prefix = SPI_getvalue(row, desc, COL_PREFIX); if (state->table_prefix == NULL) elog(ERROR, "table prefix NULL"); state->next_event_id = SPI_getbinval(row, desc, COL_EVENT_ID, &isnull); if (isnull) elog(ERROR, "Seq name NULL"); }
char *lookup_field_mapping(MemoryContext cxt, Oid tableRelId, char *fieldname) { char *definition = NULL; StringInfo query; SPI_connect(); query = makeStringInfo(); appendStringInfo(query, "select definition from zdb_mappings where table_name = %d::regclass and field_name = %s;", tableRelId, TextDatumGetCString(DirectFunctionCall1(quote_literal, CStringGetTextDatum(fieldname)))); if (SPI_execute(query->data, true, 2) != SPI_OK_SELECT) elog(ERROR, "Problem looking up analysis thing with query: %s", query->data); if (SPI_processed > 1) { elog(ERROR, "Too many mappings found"); } else if (SPI_processed == 1) { char *json = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1); Size len = strlen(json); definition = (char *) MemoryContextAllocZero(cxt, (Size) len + 1); memcpy(definition, json, len); } SPI_finish(); return definition; }
char *lookup_analysis_thing(MemoryContext cxt, char *thing) { char *definition = ""; StringInfo query; SPI_connect(); query = makeStringInfo(); appendStringInfo(query, "select (to_json(name) || ':' || definition) from %s;", TextDatumGetCString(DirectFunctionCall1(quote_ident, CStringGetTextDatum(thing)))); if (SPI_execute(query->data, true, 0) != SPI_OK_SELECT) elog(ERROR, "Problem looking up analysis thing with query: %s", query->data); if (SPI_processed > 0) { StringInfo json = makeStringInfo(); int i; for (i = 0; i < SPI_processed; i++) { if (i > 0) appendStringInfoCharMacro(json, ','); appendStringInfo(json, "%s", SPI_getvalue(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1)); } definition = (char *) MemoryContextAllocZero(cxt, (Size) json->len + 1); memcpy(definition, json->data, json->len); } SPI_finish(); return definition; }
/* * Ensure that the environment is sane. * This involves checking the Postgresql version, and if in network mode * also establishing a connection to a receiver. */ int ensure_valid_environment(void) { StringInfoData buf; int retval; char* pgversion; SPITupleTable *coltuptable; SetCurrentStatementStartTimestamp(); StartTransactionCommand(); SPI_connect(); PushActiveSnapshot(GetTransactionSnapshot()); /* Ensure compatible version */ pgstat_report_activity(STATE_RUNNING, "verifying compatible postgres version"); initStringInfo(&buf); appendStringInfo(&buf, "select version();" ); retval = SPI_execute(buf.data, false, 0); if (retval != SPI_OK_SELECT) { elog(FATAL, "Unable to query postgres version %d", retval); SPI_finish(); PopActiveSnapshot(); CommitTransactionCommand(); return 1; } coltuptable = SPI_tuptable; pgversion = SPI_getvalue(coltuptable->vals[0], coltuptable->tupdesc, 1); if(strstr(pgversion, "PostgreSQL 9.3") == NULL) { elog(FATAL, "Unsupported Postgresql version"); SPI_finish(); PopActiveSnapshot(); CommitTransactionCommand(); return 1; } SPI_finish(); PopActiveSnapshot(); CommitTransactionCommand(); /* * Attempt to establish a connection if the output mode is network. */ if (strcmp(output_mode, "network") == 0) { retval = establish_connection(); if (retval == 2) { elog(LOG, "Error : Failed to connect to antenna please check domain is available from host."); } } //TODO verify logging directory is accessible when csv mode. elog(LOG, "Pgsampler Initialized"); return 0; }
/* * Performs Actual Query execution */ int Persistent_ExecuteQuery(char const *query, bool readOnlyQuery) { StringInfoData sqlstmt; int ret; int proc = 0; Assert (query); Insist(connected); /*Initializations*/ sqlstmt.data = NULL; /* Assemble our query string */ initStringInfo(&sqlstmt); appendStringInfo(&sqlstmt,"%s",query); PG_TRY(); { /*XXX: Need to set the snapshot here. Reason - Unknown*/ ActiveSnapshot = SnapshotNow; /* Run the query. */ ret = SPI_execute(sqlstmt.data, readOnlyQuery, 0); proc = SPI_processed; if (ret > 0 && SPI_tuptable != NULL) { TupleDesc tupdesc = SPI_tuptable->tupdesc; SPITupleTable* tuptable = SPI_tuptable; int i,j; char localbuf[8192]; for (j = 0; j< proc; j++) { HeapTuple tuple = tuptable->vals[j]; for (i = 1, localbuf[0] = '\0'; i <= tupdesc->natts; i++) { snprintf(localbuf + strlen (localbuf), sizeof(localbuf) - strlen(localbuf), " %s%s", SPI_getvalue(tuple, tupdesc, i), (i == tupdesc->natts) ? " " : " |"); } elog (LOG, "==>: %s", localbuf); } } } /* Clean up in case of error. */ PG_CATCH(); { pfree(sqlstmt.data); PG_RE_THROW(); } PG_END_TRY(); pfree(sqlstmt.data); return proc; }
char* pgr_SPI_getText(HeapTuple *tuple, TupleDesc *tupdesc, Column_info_t info) { char* value = NULL; char* val = NULL; val = SPI_getvalue(*tuple, *tupdesc, info.colNumber); value = DatumGetCString(&val); pfree(val); return value; }
Datum cdb_get_oid(PG_FUNCTION_ARGS) { int result; if ( SPI_OK_CONNECT != SPI_connect() ) { ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), errmsg("SPI_connect failed in cdb_eget_oid" ))); } if ( SPI_OK_UTILITY != SPI_execute( "CREATE TEMPORARY TABLE pgdump_oid (dummy integer) WITH OIDS", false, 0 ) ) { ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), errmsg("SPI_execute failed in cdb_get_oid" ))); } if ( SPI_OK_INSERT != SPI_execute( "insert into pgdump_oid values(0)", false, 0 ) ) { ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), errmsg("SPI_execute failed to insert a row into pgdump_oid in cdb_get_oid" ))); } if ( SPI_OK_SELECT != SPI_execute( "select oid from pgdump_oid", false, 0 ) ) { ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), errmsg("SPI_execute failed in cdb_get_oid" ))); } if ( SPI_processed == 0 ) ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), errmsg("No rows in pgdump_oid in cdb_get_oid" ))); TupleDesc tupdesc = SPI_tuptable->tupdesc; result = atoi( SPI_getvalue( SPI_tuptable->vals[0], tupdesc, 1)); if ( SPI_OK_UTILITY != SPI_execute( "DROP TABLE pgdump_oid", false, 0 ) ) { ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), errmsg("SPI_execute failed in cdb_get_oid" ))); } SPI_finish(); PG_RETURN_INT32(result); }
/* * This function will set a string in shared memory which is the name of the database to connect to * the next time the background worker restarts. Because a bgworker can only connect to one database * at a time, and some catalogs and stats are scoped to the current database, the bg worker * periodically restarts to collect latest stats from another database. * */ int set_next_db_target(void) { int retval, processed; StringInfoData buf; SPITupleTable *coltuptable; char* next_db_target; SetCurrentStatementStartTimestamp(); StartTransactionCommand(); SPI_connect(); PushActiveSnapshot(GetTransactionSnapshot()); /* get sorted list of databases, find one after target_db*/ initStringInfo(&buf); appendStringInfo(&buf, "SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1') AND datallowconn IS TRUE AND datname > '%s' ORDER BY datname ASC LIMIT 1;", target_db ); retval = SPI_execute(buf.data, false, 0); if (retval != SPI_OK_SELECT) { elog(FATAL, "Database information collection failed"); // FAIL RETURN 1 } processed = SPI_processed; if(processed == 0) { //No matching records so pick first database. resetStringInfo(&buf); appendStringInfoString(&buf, "SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1') AND datallowconn IS TRUE ORDER BY datname ASC LIMIT 1;" ); retval = SPI_execute(buf.data, false, 0); if (retval != SPI_OK_SELECT) { elog(FATAL, "Database information collection failed"); // FAIL RETURN 1 } } coltuptable = SPI_tuptable; next_db_target = SPI_getvalue(coltuptable->vals[0], coltuptable->tupdesc, 1); // elog(LOG, "NEXTDB TARGET: %s", next_db_target); //print next target db strcpy(pgsampler_state->next_db, next_db_target); SPI_finish(); PopActiveSnapshot(); CommitTransactionCommand(); return 0; }
/** * The given query must return exactly one row with exactly one value * * Returns a value allocated with malloc, so the returned char* must bee free'd */ static char * performSimpleQuery_(const char * query) { char * ret = NULL; SPI_connect(); int result = SPI_exec(query, 1); if ( result >= 0 ) ret = strdup( SPI_getvalue( * SPI_tuptable->vals, SPI_tuptable->tupdesc, 1 ) ); SPI_finish(); if ( result < 0 ) return NULL; return ret; }
static void override_fields(struct PgqTriggerEvent *ev) { TriggerData *tg = ev->tgdata; int res, i; char *val; /* no overrides */ if (!ev->tgargs) return; for (i = 0; i < EV_NFIELDS; i++) { if (!ev->tgargs->query[i]) continue; res = qb_execute(ev->tgargs->query[i], tg); if (res != SPI_OK_SELECT) elog(ERROR, "Override query failed"); if (SPI_processed != 1) elog(ERROR, "Expect 1 row from override query, got %d", SPI_processed); /* special handling for EV_WHEN */ if (i == EV_WHEN) { bool isnull; Oid oid = SPI_gettypeid(SPI_tuptable->tupdesc, 1); Datum res; if (oid != BOOLOID) elog(ERROR, "when= query result must be boolean, got=%u", oid); res = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull); if (isnull) elog(ERROR, "when= should not be NULL"); if (DatumGetBool(res) == 0) ev->skip_event = true; continue; } /* normal field */ val = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1); if (ev->field[i]) { pfree(ev->field[i]->data); pfree(ev->field[i]); ev->field[i] = NULL; } if (val) { ev->field[i] = pgq_init_varbuf(); appendStringInfoString(ev->field[i], val); } } }
Oid *find_all_zdb_indexes(int *many) { Oid *indexes = NULL; int i; SPI_connect(); SPI_execute("select oid from pg_class where relam = (select oid from pg_am where amname = 'zombodb');", true, 0); *many = SPI_processed; if (SPI_processed > 0) { indexes = (Oid *) MemoryContextAlloc(TopTransactionContext, sizeof(Oid) * SPI_processed); for (i = 0; i < SPI_processed; i++) indexes[i] = (Oid) atoi(SPI_getvalue(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1)); } SPI_finish(); return indexes; }
static void fill_magic_columns(PgqTriggerEvent *ev) { TriggerData *tg = ev->tgdata; int i; char *col_name, *col_value; StringInfo *dst = NULL; TupleDesc tupdesc = tg->tg_relation->rd_att; HeapTuple row; if (TRIGGER_FIRED_BY_UPDATE(tg->tg_event)) row = tg->tg_newtuple; else row = tg->tg_trigtuple; for (i = 0; i < tupdesc->natts; i++) { /* Skip dropped columns */ if (tupdesc->attrs[i]->attisdropped) continue; col_name = NameStr(tupdesc->attrs[i]->attname); if (!is_magic_field(col_name)) continue; if (strcmp(col_name, "_pgq_ev_type") == 0) dst = &ev->field[EV_TYPE]; else if (strcmp(col_name, "_pgq_ev_data") == 0) dst = &ev->field[EV_DATA]; else if (strcmp(col_name, "_pgq_ev_extra1") == 0) dst = &ev->field[EV_EXTRA1]; else if (strcmp(col_name, "_pgq_ev_extra2") == 0) dst = &ev->field[EV_EXTRA2]; else if (strcmp(col_name, "_pgq_ev_extra3") == 0) dst = &ev->field[EV_EXTRA3]; else if (strcmp(col_name, "_pgq_ev_extra4") == 0) dst = &ev->field[EV_EXTRA4]; else elog(ERROR, "Unknown magic column: %s", col_name); col_value = SPI_getvalue(row, tupdesc, i + 1); if (col_value != NULL) { *dst = pgq_init_varbuf(); appendStringInfoString(*dst, col_value); } else { *dst = NULL; } } }
char* GetProj4StringSPI(int srid) { static int maxproj4len = 512; int spi_result; char *proj_str = palloc(maxproj4len); char proj4_spi_buffer[256]; /* Connect */ spi_result = SPI_connect(); if (spi_result != SPI_OK_CONNECT) { elog(ERROR, "GetProj4StringSPI: Could not connect to database using SPI"); } /* Execute the lookup query */ snprintf(proj4_spi_buffer, 255, "SELECT proj4text FROM spatial_ref_sys WHERE srid = %d LIMIT 1", srid); spi_result = SPI_exec(proj4_spi_buffer, 1); /* Read back the PROJ4 text */ if (spi_result == SPI_OK_SELECT && SPI_processed > 0) { /* Select the first (and only tuple) */ TupleDesc tupdesc = SPI_tuptable->tupdesc; SPITupleTable *tuptable = SPI_tuptable; HeapTuple tuple = tuptable->vals[0]; /* Make a projection object out of it */ strncpy(proj_str, SPI_getvalue(tuple, tupdesc, 1), maxproj4len - 1); } else { elog(ERROR, "GetProj4StringSPI: Cannot find SRID (%d) in spatial_ref_sys", srid); } spi_result = SPI_finish(); if (spi_result != SPI_OK_FINISH) { elog(ERROR, "GetProj4StringSPI: Could not disconnect from database using SPI"); } return proj_str; }
/* * Fill table information in hash table. */ static void fill_tbl_info(Relation rel, struct PgqTableInfo *info) { StringInfo pkeys; Datum values[1]; const char *name = find_table_name(rel); TupleDesc desc; HeapTuple row; bool isnull; int res, i, attno; /* allow reset ASAP, but ignore it in this call */ info->invalid = false; /* load pkeys */ values[0] = ObjectIdGetDatum(rel->rd_id); res = SPI_execute_plan(pkey_plan, values, NULL, false, 0); if (res != SPI_OK_SELECT) elog(ERROR, "pkey_plan exec failed"); /* * Fill info */ desc = SPI_tuptable->tupdesc; pkeys = makeStringInfo(); info->n_pkeys = SPI_processed; info->table_name = MemoryContextStrdup(tbl_cache_ctx, name); info->pkey_attno = MemoryContextAlloc(tbl_cache_ctx, info->n_pkeys * sizeof(int)); for (i = 0; i < SPI_processed; i++) { row = SPI_tuptable->vals[i]; attno = DatumGetInt16(SPI_getbinval(row, desc, 1, &isnull)); name = SPI_getvalue(row, desc, 2); info->pkey_attno[i] = attno; if (i > 0) appendStringInfoChar(pkeys, ','); appendStringInfoString(pkeys, name); } info->pkey_list = MemoryContextStrdup(tbl_cache_ctx, pkeys->data); info->tg_cache = NULL; }
char * getNamedGeometryAsWKT(const char * locationName) { char * query = build_placeNameQuery(locationName); if ( SPI_execute(query, true, 1) != SPI_OK_SELECT ) ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg( "Error when performing placename query"))); pfree(query); if ( SPI_processed == 0 ) return NULL; // ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg( // "unable to find place name"))); else if ( SPI_processed != 1 ) ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg( "too many place names returned!"))); return SPI_getvalue(* SPI_tuptable->vals, SPI_tuptable->tupdesc, 1); }
static void fetch_restrict(HeapTuple *tuple, TupleDesc *tupdesc, restrict_columns_t *restrict_columns, restrict_t *rest) { Datum binval; bool isnull; int t; for(t=0; t<MAX_RULE_LENGTH;++t) rest->via[t] = -1; binval = SPI_getbinval(*tuple, *tupdesc, restrict_columns->target_id, &isnull); if (isnull) elog(ERROR, "target_id contains a null value"); rest->target_id = DatumGetInt32(binval); binval = SPI_getbinval(*tuple, *tupdesc, restrict_columns->to_cost, &isnull); if (isnull) elog(ERROR, "to_cost contains a null value"); rest->to_cost = DatumGetFloat8(binval); char *str = DatumGetCString(SPI_getvalue(*tuple, *tupdesc, restrict_columns->via_path)); //PGR_DBG("restriction: %f, %i, %s", rest->to_cost, rest->target_id, str); if (str != NULL) { char* pch = NULL; int ci = 0; pch = (char *)strtok (str," ,"); while (pch != NULL && ci < MAX_RULE_LENGTH) { rest->via[ci] = atoi(pch); //PGR_DBG(" rest->via[%i]=%i", ci, rest->via[ci]); ci++; pch = (char *)strtok (NULL, " ,"); } } }
Datum get_group_name(PG_FUNCTION_ARGS) { int group_id = PG_GETARG_INT32(0); int ret = SPI_connect(); if (ret < 0) elog(ERROR, "get_group_name: SPI_connect returned %d", ret); char buf[1024]; sprintf(buf, "SELECT get_group_name_by_id(%d)", group_id); elog (INFO, "get_group_name: %s", buf); ret = SPI_exec(buf, 10); if (ret < 0) elog(ERROR, "get_group_name: SPI_exec returned %d", ret); else elog(INFO, "get_group_name: SPI_exec succeeded"); char *group_name = SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1); SPI_finish(); elog (INFO, "get_group_name: %s", group_name); text *result = 0; if (0 == group_name) { elog(ERROR, "get_group_name: SPI_getvalue returned null"); result = (text *)palloc(VARHDRSZ); SET_VARSIZE(result, VARHDRSZ); } else { int len = strlen(group_name); result = (text *)palloc(VARHDRSZ + len); SET_VARSIZE(result, VARHDRSZ + len); memcpy(VARDATA(result), group_name, len); } PG_RETURN_TEXT_P(result); }
Oid *findZDBIndexes(Oid relid, int *many) { Oid *indexes = NULL; StringInfo sql; int i; SPI_connect(); sql = makeStringInfo(); appendStringInfo(sql, "select indexrelid " "from pg_index " "where indrelid = %d " " and indclass[0] = (select oid from pg_opclass where opcmethod = (select oid from pg_am where amname = 'zombodb') and opcname = 'zombodb_tid_ops')", relid); SPI_execute(sql->data, true, 1); *many = SPI_processed; if (SPI_processed > 0) { indexes = (Oid *) MemoryContextAlloc(TopTransactionContext, sizeof(Oid) * SPI_processed); for (i = 0; i < SPI_processed; i++) indexes[i] = (Oid) atoi(SPI_getvalue(SPI_tuptable->vals[i], SPI_tuptable->tupdesc, 1)); } SPI_finish(); return indexes; }
void pgq_urlenc_row(PgqTriggerEvent *ev, HeapTuple row, StringInfo buf) { TriggerData *tg = ev->tgdata; TupleDesc tupdesc = tg->tg_relation->rd_att; bool first = true; int i; const char *col_ident, *col_value; int attkind_idx = -1; for (i = 0; i < tg->tg_relation->rd_att->natts; i++) { /* Skip dropped columns */ if (tupdesc->attrs[i]->attisdropped) continue; attkind_idx++; if (pgqtriga_skip_col(ev, i, attkind_idx)) continue; if (first) first = false; else appendStringInfoChar(buf, '&'); /* quote column name */ col_ident = SPI_fname(tupdesc, i + 1); pgq_encode_cstring(buf, col_ident, TBUF_QUOTE_URLENC); /* quote column value */ col_value = SPI_getvalue(row, tupdesc, i + 1); if (col_value != NULL) { appendStringInfoChar(buf, '='); pgq_encode_cstring(buf, col_value, TBUF_QUOTE_URLENC); } } }