prestogres 0.4.7 → 0.4.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/ChangeLog +14 -0
- data/VERSION +1 -1
- data/pgpool2/child.c +4 -1
- data/pgpool2/pool.h +3 -1
- data/pgpool2/pool_hba.c +11 -7
- data/pgpool2/pool_query_context.c +30 -0
- data/pgpool2/pool_select_walker.c +9 -0
- data/pgpool2/pool_session_context.h +2 -0
- data/pgsql/prestogres.py +42 -6
- data/pgsql/setup.sql +10 -14
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MDM4ZjYxNWJhNDE5YjBlOGViYTlmNmEzZjRiOGMxNzMzNjM4ZjY2OA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OTNjYWU2MGE3ZDkxZmI0YTZmZDA3ZWQ0NGU4YTA1NzlmZjg5OGNlOA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OGFmNDhjMjQwNjljMzBhZGRmZWVjNThjODExY2MxNjM0MzY1M2MzZDMyMDFl
|
10
|
+
NmE1NWE1MjIzMDQ0ZmFjZjE0NDE0MTdhOWVkM2RjYTFkMmIzN2JkOTU5NDc0
|
11
|
+
ZmI2NWQ1NDJhZWIwZTExNDUzYTUyNzVjOTkyMGM0N2E0YWYxZGY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YmIzYjE0OGNiMzQzYTI2ZGZkNGFiNTRmYzJhMDNhNzAwMDlhYjZmNjBkZmU3
|
14
|
+
MTJjODQxZTYxZjJmNTkwMDdkOTFhYWM5ZTg1YTdiNGRkYTllYTE1Zjc4ZjEz
|
15
|
+
ZjlmMGMzNTllYjlmYjQ0N2U5OWEzMjM5OTk5ZGZkNjI4NWY3ZmY=
|
data/ChangeLog
CHANGED
@@ -1,4 +1,18 @@
|
|
1
1
|
|
2
|
+
2014-07-18 version 0.4.8:
|
3
|
+
|
4
|
+
You need to re-initialize PostgreSQL data directly when you upgrade.
|
5
|
+
|
6
|
+
* Sort table and schema names to preserve oid even if presto connectors don't
|
7
|
+
gurantee order
|
8
|
+
* System catalog queries create user and switches role to emulate login user
|
9
|
+
name
|
10
|
+
* System catalog queries update pg_database to be consistent with login
|
11
|
+
databae name
|
12
|
+
* Added support for information_schema
|
13
|
+
* Added special type conversion rules to support information_schema
|
14
|
+
|
15
|
+
|
2
16
|
2014-06-26 version 0.4.7:
|
3
17
|
|
4
18
|
* Fixed a problem where multi-line queries don't run correctly
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.8
|
data/pgpool2/child.c
CHANGED
@@ -296,7 +296,7 @@ void do_child(int unix_fd, int inet_fd)
|
|
296
296
|
}
|
297
297
|
|
298
298
|
/* this should run before ClientAuthentication */
|
299
|
-
|
299
|
+
pool_prestogres_init_login(sp);
|
300
300
|
|
301
301
|
if (pool_config->enable_pool_hba)
|
302
302
|
{
|
@@ -423,6 +423,9 @@ void do_child(int unix_fd, int inet_fd)
|
|
423
423
|
/* Mark this connection pool is connected from frontend */
|
424
424
|
pool_coninfo_set_frontend_connected(pool_get_process_context()->proc_id, pool_pool_index());
|
425
425
|
|
426
|
+
///* Set initial search_path */
|
427
|
+
//prestogres_set_initial_search_path(backend);
|
428
|
+
|
426
429
|
/* query process loop */
|
427
430
|
for (;;)
|
428
431
|
{
|
data/pgpool2/pool.h
CHANGED
@@ -648,10 +648,12 @@ extern const char* presto_user;
|
|
648
648
|
extern const char* presto_catalog;
|
649
649
|
extern const char* presto_schema;
|
650
650
|
extern const char* presto_external_auth_prog;
|
651
|
+
extern const char* pool_user;
|
652
|
+
extern const char* pool_database;
|
651
653
|
|
652
654
|
int send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt);
|
653
655
|
int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize);
|
654
656
|
|
655
|
-
void
|
657
|
+
void pool_prestogres_init_login(StartupPacket *sp);
|
656
658
|
|
657
659
|
#endif /* POOL_H */
|
data/pgpool2/pool_hba.c
CHANGED
@@ -74,6 +74,8 @@ const char* presto_user = NULL;
|
|
74
74
|
const char* presto_catalog = NULL;
|
75
75
|
const char* presto_schema = NULL;
|
76
76
|
const char* presto_external_auth_prog = NULL;
|
77
|
+
const char* pool_user = NULL;
|
78
|
+
const char* pool_database = NULL;
|
77
79
|
|
78
80
|
static bool prestogres_hba_set_session_info(POOL_CONNECTION *frontend, const char* key, const char* value);
|
79
81
|
static void prestogres_hba_parse_arg(POOL_CONNECTION *frontend, const char* arg);
|
@@ -1727,23 +1729,25 @@ static POOL_STATUS pool_prestogres_hba_auth_external(POOL_CONNECTION *frontend)
|
|
1727
1729
|
return POOL_CONTINUE;
|
1728
1730
|
}
|
1729
1731
|
|
1730
|
-
void
|
1732
|
+
void pool_prestogres_init_login(StartupPacket *sp)
|
1731
1733
|
{
|
1734
|
+
pool_user = strdup(sp->user);
|
1735
|
+
pool_database = strdup(sp->database);
|
1732
1736
|
if (presto_server == NULL) {
|
1733
1737
|
presto_server = pool_config->presto_server;
|
1734
1738
|
}
|
1735
1739
|
if (presto_user == NULL) {
|
1736
|
-
presto_user =
|
1740
|
+
presto_user = pool_user;
|
1737
1741
|
}
|
1738
1742
|
if (presto_catalog == NULL) {
|
1739
1743
|
presto_catalog = pool_config->presto_catalog;
|
1740
1744
|
}
|
1741
1745
|
if (presto_schema == NULL) {
|
1742
|
-
presto_schema =
|
1746
|
+
presto_schema = pool_database;
|
1743
1747
|
}
|
1744
|
-
pool_debug("
|
1745
|
-
pool_debug("
|
1746
|
-
pool_debug("
|
1747
|
-
pool_debug("
|
1748
|
+
pool_debug("pool_prestogres_init_login: presto_server: %s", presto_server);
|
1749
|
+
pool_debug("pool_prestogres_init_login: presto_user: %s", presto_user);
|
1750
|
+
pool_debug("pool_prestogres_init_login: presto_catalog: %s", presto_catalog);
|
1751
|
+
pool_debug("pool_prestogres_init_login: presto_schema: %s", presto_schema);
|
1748
1752
|
}
|
1749
1753
|
|
@@ -482,6 +482,10 @@ static void run_and_rewrite_system_catalog_query(POOL_SESSION_CONTEXT* session_c
|
|
482
482
|
buffer = strcpy_capped(buffer, bufend - buffer, "', E'");
|
483
483
|
buffer = strcpy_capped_escaped(buffer, bufend - buffer, presto_schema, "'\\");
|
484
484
|
buffer = strcpy_capped(buffer, bufend - buffer, "', E'");
|
485
|
+
buffer = strcpy_capped_escaped(buffer, bufend - buffer, pool_user, "'\\");
|
486
|
+
buffer = strcpy_capped(buffer, bufend - buffer, "', E'");
|
487
|
+
buffer = strcpy_capped_escaped(buffer, bufend - buffer, pool_database, "'\\");
|
488
|
+
buffer = strcpy_capped(buffer, bufend - buffer, "', E'");
|
485
489
|
buffer = strcpy_capped_escaped(buffer, bufend - buffer, PRESTO_RESULT_TABLE_NAME, "'\\");
|
486
490
|
buffer = strcpy_capped(buffer, bufend - buffer, "', E'");
|
487
491
|
buffer = strcpy_capped_escaped(buffer, bufend - buffer, query_context->original_query, "'\\");
|
@@ -628,6 +632,32 @@ static void run_and_rewrite_presto_query(POOL_SESSION_CONTEXT* session_context,
|
|
628
632
|
do_replace_query(query_context, rewrite_query_string_buffer);
|
629
633
|
}
|
630
634
|
|
635
|
+
//void prestogres_set_initial_search_path(POOL_CONNECTION_POOL *backend)
|
636
|
+
//{
|
637
|
+
// char *buffer, *bufend;
|
638
|
+
// POOL_STATUS status;
|
639
|
+
// POOL_SELECT_RESULT *res;
|
640
|
+
//
|
641
|
+
// buffer = rewrite_query_string_buffer;
|
642
|
+
// bufend = buffer + sizeof(rewrite_query_string_buffer);
|
643
|
+
//
|
644
|
+
// buffer = strcpy_capped(buffer, bufend - buffer, "set search_path to E'");
|
645
|
+
// buffer = strcpy_capped_escaped(buffer, bufend - buffer, presto_schema, "'\\");
|
646
|
+
// buffer = strcpy_capped(buffer, bufend - buffer, "'");
|
647
|
+
//
|
648
|
+
// if (buffer == NULL) {
|
649
|
+
// pool_error("prestogres_set_initial_search_path: failed to build a query");
|
650
|
+
// return;
|
651
|
+
// }
|
652
|
+
//
|
653
|
+
// status = do_query(MASTER(backend), rewrite_query_string_buffer, &res, MAJOR(backend));
|
654
|
+
// free_select_result(res);
|
655
|
+
//
|
656
|
+
// if (status != POOL_CONTINUE) {
|
657
|
+
// pool_error("prestogres_set_initial_search_path: SET command failed");
|
658
|
+
// }
|
659
|
+
//}
|
660
|
+
|
631
661
|
/*
|
632
662
|
* Decide where to send queries(thus expecting response)
|
633
663
|
*/
|
@@ -323,6 +323,15 @@ system_catalog_walker(Node *node, void *context)
|
|
323
323
|
ctx->has_system_catalog = true;
|
324
324
|
return false;
|
325
325
|
}
|
326
|
+
|
327
|
+
if (rgv->schemaname != NULL && strcmp(rgv->schemaname, "information_schema") == 0)
|
328
|
+
{
|
329
|
+
/* This could cause false-negative match. If the client puts information_schema
|
330
|
+
* to search_path, and it doesn't explicitly specify schem name, here can't match
|
331
|
+
*/
|
332
|
+
ctx->has_system_catalog = true;
|
333
|
+
return false;
|
334
|
+
}
|
326
335
|
}
|
327
336
|
return raw_expression_tree_walker(node, system_catalog_walker, context);
|
328
337
|
}
|
@@ -195,6 +195,8 @@ extern bool pool_is_command_success(void);
|
|
195
195
|
extern void pool_copy_prep_where(bool *src, bool *dest);
|
196
196
|
extern bool can_query_context_destroy(POOL_QUERY_CONTEXT *qc);
|
197
197
|
|
198
|
+
//extern void prestogres_set_initial_search_path(POOL_CONNECTION_POOL *backend);
|
199
|
+
|
198
200
|
#ifdef NOT_USED
|
199
201
|
extern void pool_add_prep_where(char *name, bool *map);
|
200
202
|
extern bool *pool_get_prep_where(char *name);
|
data/pgsql/prestogres.py
CHANGED
@@ -176,10 +176,28 @@ def _get_session_time_zone():
|
|
176
176
|
rows = plpy.execute("show timezone")
|
177
177
|
return rows[0].values()[0]
|
178
178
|
|
179
|
+
def _get_session_search_path_array():
|
180
|
+
rows = plpy.execute("select ('{' || current_setting('search_path') || '}')::text[]")
|
181
|
+
return rows[0].values()[0]
|
182
|
+
|
179
183
|
QueryResult = namedtuple("QueryResult", ("column_names", "column_types", "result"))
|
180
184
|
|
181
185
|
OidToTypeNameMapping = {}
|
182
186
|
|
187
|
+
# information_schema on PostgreSQL have some special column types where
|
188
|
+
# CREATE TABLE can't use the types (although SELECT returns the types).
|
189
|
+
def _pg_convert_infoschema_type(infoschema_type):
|
190
|
+
if infoschema_type == "sql_identifier":
|
191
|
+
return "name"
|
192
|
+
if infoschema_type == "cardinal_number":
|
193
|
+
return "int"
|
194
|
+
elif infoschema_type == "character_data":
|
195
|
+
return "name"
|
196
|
+
elif infoschema_type == "yes_or_no":
|
197
|
+
return "text"
|
198
|
+
else:
|
199
|
+
return infoschema_type
|
200
|
+
|
183
201
|
def _load_oid_to_type_name_mapping(oids):
|
184
202
|
oids = filter(lambda oid: oid not in OidToTypeNameMapping, oids)
|
185
203
|
if oids:
|
@@ -187,7 +205,8 @@ def _load_oid_to_type_name_mapping(oids):
|
|
187
205
|
" from pg_catalog.pg_type" \
|
188
206
|
" where oid in (%s)") % (", ".join(map(str, oids)))
|
189
207
|
for row in plpy.execute(sql):
|
190
|
-
|
208
|
+
type_name = _pg_convert_infoschema_type(row["typname"])
|
209
|
+
OidToTypeNameMapping[int(row["oid"])] = type_name
|
191
210
|
|
192
211
|
return OidToTypeNameMapping
|
193
212
|
|
@@ -197,6 +216,11 @@ SchemaCacheEntry = SchemaCache()
|
|
197
216
|
|
198
217
|
def run_presto_as_temp_table(server, user, catalog, schema, result_table, query):
|
199
218
|
try:
|
219
|
+
search_path = _get_session_search_path_array()
|
220
|
+
if search_path != ['$user', 'public'] and len(search_path) > 0:
|
221
|
+
# search_path is changed explicitly. Use the first schema
|
222
|
+
schema = search_path[0]
|
223
|
+
|
200
224
|
client = presto_client.Client(server=server, user=user, catalog=catalog, schema=schema, time_zone=_get_session_time_zone())
|
201
225
|
|
202
226
|
create_sql = "create temporary table %s (\n " % plpy.quote_ident(result_table)
|
@@ -234,7 +258,7 @@ def run_presto_as_temp_table(server, user, catalog, schema, result_table, query)
|
|
234
258
|
e.__class__.__module__ = "__main__"
|
235
259
|
raise
|
236
260
|
|
237
|
-
def run_system_catalog_as_temp_table(server, user, catalog, schema, result_table, query):
|
261
|
+
def run_system_catalog_as_temp_table(server, user, catalog, schema, login_user, login_database, result_table, query):
|
238
262
|
try:
|
239
263
|
client = presto_client.Client(server=server, user=user, catalog=catalog, schema=schema, time_zone=_get_session_time_zone())
|
240
264
|
|
@@ -288,16 +312,25 @@ def run_system_catalog_as_temp_table(server, user, catalog, schema, result_table
|
|
288
312
|
statements = []
|
289
313
|
schema_names = []
|
290
314
|
|
315
|
+
# create a restricted user using the same name with the login user name to pgpool2
|
316
|
+
statements.append(
|
317
|
+
"do $$ begin if not exists (select * from pg_catalog.pg_roles where rolname=%s) then create role %s with login; end if; end $$" % \
|
318
|
+
(plpy.quote_literal(login_user), plpy.quote_ident(login_user)))
|
319
|
+
|
320
|
+
# grant access on the all table holders to the restricted user
|
321
|
+
statements.append("grant select on all tables in schema prestogres_catalog to %s" % \
|
322
|
+
plpy.quote_ident(login_user))
|
323
|
+
|
291
324
|
table_holder_id = 0
|
292
325
|
|
293
|
-
for schema_name, tables in schemas.items():
|
326
|
+
for schema_name, tables in sorted(schemas.items(), key=lambda (k,v): k):
|
294
327
|
if schema_name == "sys" or schema_name == "information_schema":
|
295
328
|
# skip system schemas
|
296
329
|
continue
|
297
330
|
|
298
331
|
schema_names.append(schema_name)
|
299
332
|
|
300
|
-
for table_name, columns in tables.items():
|
333
|
+
for table_name, columns in sorted(tables.items(), key=lambda (k,v): k):
|
301
334
|
# table schema
|
302
335
|
column_names = []
|
303
336
|
column_types = []
|
@@ -369,8 +402,11 @@ def run_system_catalog_as_temp_table(server, user, catalog, schema, result_table
|
|
369
402
|
plpy.execute("drop schema %s" % plpy.quote_ident(row["schema_name"]))
|
370
403
|
|
371
404
|
# update pg_database
|
372
|
-
|
373
|
-
|
405
|
+
plpy.execute("update pg_database set datname=%s where datname=current_database()" % \
|
406
|
+
plpy.quote_literal(schema_name))
|
407
|
+
|
408
|
+
# switch to the restricted role
|
409
|
+
plpy.execute("set role to %s" % plpy.quote_ident(login_user))
|
374
410
|
|
375
411
|
# run the actual query and save result
|
376
412
|
metadata = plpy.execute(query)
|
data/pgsql/setup.sql
CHANGED
@@ -6,27 +6,23 @@ drop schema if exists prestogres_catalog cascade;
|
|
6
6
|
create schema prestogres_catalog;
|
7
7
|
|
8
8
|
create or replace function prestogres_catalog.run_presto_as_temp_table(
|
9
|
-
"server" text,
|
10
|
-
"
|
11
|
-
"catalog" text,
|
12
|
-
"schema" text,
|
13
|
-
"table_name" text,
|
14
|
-
"query" text)
|
9
|
+
"server" text, "user" text, "catalog" text, "schema" text,
|
10
|
+
"result_table" text, "query" text)
|
15
11
|
returns void as $$
|
16
12
|
import prestogres
|
17
|
-
prestogres.run_presto_as_temp_table(
|
13
|
+
prestogres.run_presto_as_temp_table(
|
14
|
+
server, user, catalog, schema, result_table, query)
|
18
15
|
$$ language plpythonu;
|
19
16
|
|
20
17
|
create or replace function prestogres_catalog.run_system_catalog_as_temp_table(
|
21
|
-
"server" text,
|
22
|
-
"
|
23
|
-
"
|
24
|
-
"schema" text,
|
25
|
-
"table_name" text,
|
26
|
-
"query" text)
|
18
|
+
"server" text, "user" text, "catalog" text, "schema" text,
|
19
|
+
"login_user" text, "login_database" text,
|
20
|
+
"result_table" text, "query" text)
|
27
21
|
returns void as $$
|
28
22
|
import prestogres
|
29
|
-
prestogres.run_system_catalog_as_temp_table(
|
23
|
+
prestogres.run_system_catalog_as_temp_table(
|
24
|
+
server, user, catalog, schema, login_user, login_database,
|
25
|
+
result_table, query)
|
30
26
|
$$ language plpythonu;
|
31
27
|
|
32
28
|
create or replace function prestogres_catalog.create_schema_holders("count" int)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prestogres
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|