/* * Judge the table used in a query represented by node is a system * catalog or not. */ static bool is_system_catalog(char *table_name) { /* * Query to know if pg_namespace exists. PostgreSQL 7.2 or before doesn't have. */ #define HASPGNAMESPACEQUERY "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s'" /* * Query to know if the target table belongs pg_catalog schema. */ #define ISBELONGTOPGCATALOGQUERY "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = '%s' AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'" #define ISBELONGTOPGCATALOGQUERY2 "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.oid = pgpool_regclass('%s') AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'" int hasreliscatalog; bool result; static POOL_RELCACHE *hasreliscatalog_cache; static POOL_RELCACHE *relcache; POOL_CONNECTION_POOL *backend; if (table_name == NULL) { return false; } backend = pool_get_session_context()->backend; /* * Check if pg_namespace exists */ if (!hasreliscatalog_cache) { char *query; /* pgpool_regclass has been installed */ if (pool_has_pgpool_regclass()) { query = ISBELONGTOPGCATALOGQUERY2; } else { query = ISBELONGTOPGCATALOGQUERY; } hasreliscatalog_cache = pool_create_relcache(pool_config->relcache_size, query, int_register_func, int_unregister_func, false); if (hasreliscatalog_cache == NULL) { pool_error("is_system_catalog: pool_create_relcache error"); return false; } } hasreliscatalog = pool_search_relcache(hasreliscatalog_cache, backend, "pg_namespace")==0?0:1; if (hasreliscatalog) { /* * If relcache does not exist, create it. */ if (!relcache) { char *query; /* pgpool_regclass has been installed */ if (pool_has_pgpool_regclass()) { query = ISBELONGTOPGCATALOGQUERY2; } else { query = ISBELONGTOPGCATALOGQUERY; } relcache = pool_create_relcache(pool_config->relcache_size, query, int_register_func, int_unregister_func, false); if (relcache == NULL) { pool_error("is_system_catalog: pool_create_relcache error"); return false; } } /* * Search relcache. */ result = pool_search_relcache(relcache, backend, table_name)==0?false:true; return result; } /* * Pre 7.3. Just check whether the table starts with "pg_". */ return (strcasecmp(table_name, "pg_") == 0); }
/* * Get or return cached transaction isolation mode */ POOL_TRANSACTION_ISOLATION pool_get_transaction_isolation(void) { POOL_STATUS status; POOL_SELECT_RESULT *res; POOL_TRANSACTION_ISOLATION ret; if (!session_context) { pool_error("pool_get_transaction_isolation: session context is not initialized"); return POOL_UNKNOWN; } /* It seems cached result is usable. Return it. */ if (session_context->transaction_isolation != POOL_UNKNOWN) return session_context->transaction_isolation; /* No cached data is available. Ask backend. */ status = do_query(MASTER(session_context->backend), "SELECT current_setting('transaction_isolation')", &res, MAJOR(session_context->backend)); if (res->numrows <= 0) { pool_error("pool_get_transaction_isolation: do_query returns no rows"); free_select_result(res); return POOL_UNKNOWN; } if (res->data[0] == NULL) { pool_error("pool_get_transaction_isolation: do_query returns no data"); free_select_result(res); return POOL_UNKNOWN; } if (res->nullflags[0] == -1) { pool_error("pool_get_transaction_isolation: do_query returns NULL"); free_select_result(res); return POOL_UNKNOWN; } if (!strcmp(res->data[0], "read uncommitted")) ret = POOL_READ_UNCOMMITTED; else if (!strcmp(res->data[0], "read committed")) ret = POOL_READ_COMMITTED; else if (!strcmp(res->data[0], "repeatable read")) ret = POOL_REPEATABLE_READ; else if (!strcmp(res->data[0], "serializable")) ret = POOL_SERIALIZABLE; else { pool_error("pool_get_transaction_isolation: unknown transaction isolation level:%s", res->data[0]); ret = POOL_UNKNOWN; } free_select_result(res); if (ret != POOL_UNKNOWN) session_context->transaction_isolation = ret; return ret; }
int repo_add_code11_products(Repo *repo, const char *dirpath, int flags) { Repodata *data; struct parsedata pd; struct stateswitch *sw; DIR *dir; int i; data = repo_add_repodata(repo, flags); memset(&pd, 0, sizeof(pd)); pd.repo = repo; pd.pool = repo->pool; pd.data = data; pd.content = solv_malloc(256); pd.acontent = 256; for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++) { if (!pd.swtab[sw->from]) pd.swtab[sw->from] = sw; pd.sbtab[sw->to] = sw->from; } if (flags & REPO_USE_ROOTDIR) dirpath = pool_prepend_rootdir(repo->pool, dirpath); dir = opendir(dirpath); if (dir) { struct dirent *entry; struct stat st; char *fullpath; /* check for <productsdir>/baseproduct on code11 and remember its target inode */ if (stat(join2(&pd.jd, dirpath, "/", "baseproduct"), &st) == 0) /* follow symlink */ pd.baseproduct = st.st_ino; else pd.baseproduct = 0; while ((entry = readdir(dir))) { int len = strlen(entry->d_name); FILE *fp; if (len <= 5 || strcmp(entry->d_name + len - 5, ".prod") != 0) continue; fullpath = join2(&pd.jd, dirpath, "/", entry->d_name); fp = fopen(fullpath, "r"); if (!fp) { pool_error(repo->pool, 0, "%s: %s", fullpath, strerror(errno)); continue; } pd.filename = fullpath; pd.basename = entry->d_name; add_code11_product(&pd, fp); fclose(fp); } closedir(dir); } solv_free(pd.content); join_freemem(&pd.jd); if (flags & REPO_USE_ROOTDIR) solv_free((char *)dirpath); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); return 0; }
/* * Initialize per session context */ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { session_context = &session_context_d; /* Get Process context */ session_context->process_context = pool_get_process_context(); if (!session_context->process_context) { pool_error("pool_init_session_context: cannot get process context"); return; } session_context->in_transaction = false; /* Set connection info */ session_context->frontend = frontend; session_context->backend = backend; /* Initialize query context */ session_context->query_context = NULL; /* Initialize local session id */ pool_incremnet_local_session_id(); /* Initialize sent message list */ init_sent_message_list(); /* Create memory context */ session_context->memory_context = pool_memory_create(PREPARE_BLOCK_SIZE); /* Choose load balancing node if neccessary */ if (pool_config->load_balance_mode) { ProcessInfo *process_info = pool_get_my_process_info(); if (!process_info) { pool_error("pool_init_session_context: pool_get_my_process_info failed"); return; } session_context->load_balance_node_id = process_info->connection_info->load_balancing_node = select_load_balancing_node(); pool_debug("selected load balancing node: %d", backend->info->load_balancing_node); } /* Unset query is in progress */ pool_unset_query_in_progress(); /* The command in progress has not succeeded yet */ pool_unset_command_success(); /* We don't have a write query in this transaction yet */ pool_unset_writing_transaction(); /* Error doesn't occur in this transaction yet */ pool_unset_failed_transaction(); /* Forget transaction isolation mode */ pool_unset_transaction_isolation(); /* We don't skip reading from backends */ pool_unset_skip_reading_from_backends(); /* Backends have not ignored messages yet */ pool_unset_ignore_till_sync(); /* Initialize where to send map for PREPARE statemets */ #ifdef NOT_USED memset(&session_context->prep_where, 0, sizeof(session_context->prep_where)); session_context->prep_where.nelem = POOL_MAX_PREPARED_STATEMENTS; #endif /* NOT_USED */ memset(&session_context->opened_cursors, 0, sizeof(session_context->opened_cursors)); memset(&session_context->cursors_info, 0, sizeof(session_context->cursors_info)); /* Reset flag to indicate difference in number of affected tuples * in UPDATE/DELETE. */ session_context->mismatch_ntuples = false; if (pool_config->memory_cache_enabled) { session_context->query_cache_array = pool_create_query_cache_array(); session_context->num_selects = 0; } }