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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzFiNzUyZWQwMmI0MjE3YWNmMDI3OWJiYTAyODUzY2RlNTdmZGM1Ng==
4
+ MDM4ZjYxNWJhNDE5YjBlOGViYTlmNmEzZjRiOGMxNzMzNjM4ZjY2OA==
5
5
  data.tar.gz: !binary |-
6
- ZjNlMDg4Y2YzNzc1Yzc4NDM3MmQzNDI2NWI1NmMwNzU4Zjg2MWI4NQ==
6
+ OTNjYWU2MGE3ZDkxZmI0YTZmZDA3ZWQ0NGU4YTA1NzlmZjg5OGNlOA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YjExMTk2NmFkMTM0M2UwZjNjZWJiOGUyNjY2MjQ3MTU4YmIwNGI1ZWNiNWE5
10
- NTc1ZjU4MzhkNjNmOTFlY2I5Yjg4OTQ5OGY5NDA2ZGQ0OTBhZjdhMmYwNzdl
11
- MWRhZjE4N2M1YzI4MDUyNzg2NzAxZTExNTNhMGEyYWI3YjZkNjc=
9
+ OGFmNDhjMjQwNjljMzBhZGRmZWVjNThjODExY2MxNjM0MzY1M2MzZDMyMDFl
10
+ NmE1NWE1MjIzMDQ0ZmFjZjE0NDE0MTdhOWVkM2RjYTFkMmIzN2JkOTU5NDc0
11
+ ZmI2NWQ1NDJhZWIwZTExNDUzYTUyNzVjOTkyMGM0N2E0YWYxZGY=
12
12
  data.tar.gz: !binary |-
13
- OWExMzcyNjE2YzRmODI4MzhiNTU4YjEyNmUxMjc0MWE3NGI3MjhkYTU5OGM0
14
- MDczMzA1NmE4YWY4Mjk4YTJlZjQxZWQ5N2FhOWVjMmM5NjFjODM4ZDYwN2Yw
15
- N2Y1ZDljOGQ1MmJlNzVmN2Q0NjcwNmRmZjEzNzgzYmQ5MDY0YzQ=
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.7
1
+ 0.4.8
@@ -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
- pool_prestogres_set_defaults(sp);
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
  {
@@ -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 pool_prestogres_set_defaults(StartupPacket *sp);
657
+ void pool_prestogres_init_login(StartupPacket *sp);
656
658
 
657
659
  #endif /* POOL_H */
@@ -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 pool_prestogres_set_defaults(StartupPacket *sp)
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 = strdup(sp->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 = strdup(sp->database);
1746
+ presto_schema = pool_database;
1743
1747
  }
1744
- pool_debug("pool_prestogres_set_defaults: presto_server: %s", presto_server);
1745
- pool_debug("pool_prestogres_set_defaults: presto_user: %s", presto_user);
1746
- pool_debug("pool_prestogres_set_defaults: presto_catalog: %s", presto_catalog);
1747
- pool_debug("pool_prestogres_set_defaults: presto_schema: %s", presto_schema);
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);
@@ -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
- OidToTypeNameMapping[int(row["oid"])] = row["typname"]
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
- plan = plpy.prepare("update pg_database set datname=$1 where datname=current_database()", ['name'])
373
- plpy.execute(plan, [schema])
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)
@@ -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
- "user" text,
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(server, user, catalog, schema, table_name, query)
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
- "user" text,
23
- "catalog" text,
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(server, user, catalog, schema, table_name, query)
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.7
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-06-27 00:00:00.000000000 Z
11
+ date: 2014-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler