prestogres 0.4.7 → 0.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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