prestogres 0.2.0 → 0.3.0
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.
- data/.gitignore +3 -0
- data/ChangeLog +15 -0
- data/README.md +29 -30
- data/Rakefile +3 -2
- data/VERSION +1 -1
- data/bin/prestogres +69 -27
- data/config/postgresql.conf +1 -1
- data/ext/depend +13 -5
- data/pgpool2/child.c +3 -3
- data/pgpool2/pool.h +1 -1
- data/pgpool2/pool_config.c +0 -19
- data/pgpool2/pool_hba.c +7 -7
- data/pgpool2/pool_query_context.c +28 -2
- data/pgsql/prestogres.py +95 -58
- data/pgsql/setup.sql +2 -1
- metadata +28 -15
- checksums.yaml +0 -7
- data/Gemfile.lock +0 -20
    
        data/.gitignore
    CHANGED
    
    
    
        data/ChangeLog
    CHANGED
    
    | @@ -1,4 +1,18 @@ | |
| 1 1 |  | 
| 2 | 
            +
            2014-02-07 version 0.3.0:
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            * Fixed system catalog queries to support multiple schemas
         | 
| 5 | 
            +
            * Removed presto_schema parameter from pgpool.conf
         | 
| 6 | 
            +
            * Use connecting database name as the default schema name
         | 
| 7 | 
            +
            * Updated type mapping to map varchar type of Presto to varchar(100)
         | 
| 8 | 
            +
            * Implemented query cache for system catalog queries
         | 
| 9 | 
            +
            * Improved prestogres-setup command to not listen on TCP socket
         | 
| 10 | 
            +
            * Improved prestogres-setup command to support -P option
         | 
| 11 | 
            +
            * Fixed build scripts to work with bundler
         | 
| 12 | 
            +
            * Fixed build scripts to work with RubyGems >= 1.8.26
         | 
| 13 | 
            +
            * Fixed "rake install" task
         | 
| 14 | 
            +
             | 
| 15 | 
            +
             | 
| 2 16 | 
             
            2014-01-24 version 0.2.0:
         | 
| 3 17 |  | 
| 4 18 | 
             
            * Authentication mechanisms support pg_database and pg_user options to
         | 
| @@ -10,6 +24,7 @@ | |
| 10 24 | 
             
            * Queries to system catalogs delete created tables by rollbacking
         | 
| 11 25 | 
             
            subtransaction so that other sessions does not conflict
         | 
| 12 26 |  | 
| 27 | 
            +
             | 
| 13 28 | 
             
            2014-01-15 version 0.1.0:
         | 
| 14 29 |  | 
| 15 30 | 
             
            * First release
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,11 +1,11 @@ | |
| 1 1 | 
             
            # 
         | 
| 2 2 | 
             
            ## PostgreSQL protocol gateway for Presto
         | 
| 3 3 |  | 
| 4 | 
            -
            **Prestogres** is a gateway server that allows clients to use PostgreSQL protocol to run Presto | 
| 4 | 
            +
            **Prestogres** is a gateway server that allows clients to use PostgreSQL protocol to run queries on Presto.
         | 
| 5 5 |  | 
| 6 6 | 
             
            * [Presto, a distributed SQL query engine for big data](https://github.com/facebook/presto)
         | 
| 7 7 |  | 
| 8 | 
            -
             | 
| 8 | 
            +
            You can use any PostgreSQL clients (see also *Limitation* section):
         | 
| 9 9 |  | 
| 10 10 | 
             
            * `psql` command
         | 
| 11 11 | 
             
            * [PostgreSQL ODBC driver](http://psqlodbc.projects.pgfoundry.org/)
         | 
| @@ -16,6 +16,9 @@ Prestogres also offers password-based authentication and SSL. | |
| 16 16 |  | 
| 17 17 | 
             
            ## How it works?
         | 
| 18 18 |  | 
| 19 | 
            +
            Prestogres uses modified **[pgpool-II](http://www.pgpool.net/)** to rewrite queries before sending them to PostgreSQL.
         | 
| 20 | 
            +
            pgpool-II is originally an open-source middleware to provide connection pool and other features to PostgreSQL.
         | 
| 21 | 
            +
             | 
| 19 22 | 
             
            ```
         | 
| 20 23 | 
             
                   PostgreSQL protocol                     Presto protocol (HTTP)
         | 
| 21 24 | 
             
                        /                                      /
         | 
| @@ -37,6 +40,7 @@ Prestogres also offers password-based authentication and SSL. | |
| 37 40 |  | 
| 38 41 | 
             
            * Extended query is not supported ([PostgreSQL Frontend/Backend Protocol](http://www.postgresql.org/docs/9.3/static/protocol.html))
         | 
| 39 42 | 
             
              * ODBC driver needs to set **UseServerSidePrepare=0** (Server side prepare: no) property
         | 
| 43 | 
            +
              * ODBC driver needs to use "Unicode" mode
         | 
| 40 44 | 
             
              * JDBC driver needs to set **protocolVersion=2** property
         | 
| 41 45 | 
             
            * DECLARE/FETCH is not supported
         | 
| 42 46 |  | 
| @@ -46,41 +50,38 @@ Prestogres also offers password-based authentication and SSL. | |
| 46 50 | 
             
            $ gem install prestogres --no-ri --no-rdoc
         | 
| 47 51 | 
             
            ```
         | 
| 48 52 |  | 
| 49 | 
            -
            Prestogres package installs patched pgpool-II but doesn't install PostgreSQL. You need to install PostgreSQL  | 
| 53 | 
            +
            Prestogres package installs patched pgpool-II but doesn't install PostgreSQL. You need to install PostgreSQL >= 9.3 (with python support) separately.
         | 
| 50 54 |  | 
| 51 55 | 
             
            * If you don't have **gem** command, install Ruby >= 1.9.0 first
         | 
| 52 56 | 
             
            * If installation failed, you may need to install following packages using apt or yum:
         | 
| 53 57 | 
             
              * basic toolchain (gcc, make, etc.)
         | 
| 54 | 
            -
              * OpenSSL (Debian/Ubuntu: **libssl-dev**, RedHat/CentOS: **openssl-dev**)
         | 
| 55 | 
            -
              * PostgreSQL server (Debian/Ubuntu: **postgresql-server-dev**, RedHat/CentOS: **postgresql-devel**)
         | 
| 58 | 
            +
              * OpenSSL dev package (Debian/Ubuntu: **libssl-dev**, RedHat/CentOS: **openssl-dev**)
         | 
| 59 | 
            +
              * PostgreSQL server dev package (Debian/Ubuntu: **postgresql-server-dev-9.3**, RedHat/CentOS: **postgresql-devel**)
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            ### Installation FAQ
         | 
| 62 | 
            +
             | 
| 56 63 |  | 
| 57 64 | 
             
            ## Runing servers
         | 
| 58 65 |  | 
| 59 | 
            -
            You need to run 2 server programs: pgpool-II and PostgreSQL. | 
| 66 | 
            +
            You need to run 2 server programs: pgpool-II and PostgreSQL.
         | 
| 67 | 
            +
            You can use `prestogres` command to setup & run them as following:
         | 
| 60 68 |  | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 69 | 
            +
            ```sh
         | 
| 70 | 
            +
            # 1. Create a data directory:
         | 
| 63 71 | 
             
            $ prestogres -D pgdata setup
         | 
| 64 | 
            -
            ```
         | 
| 65 72 |  | 
| 66 | 
            -
            2. Configure  | 
| 67 | 
            -
            ```
         | 
| 73 | 
            +
            # 2. Configure presto_server and presto_catalog parameters at least in pgpool.conf file:
         | 
| 68 74 | 
             
            $ vi ./pgdata/pgpool/pgpool.conf
         | 
| 69 | 
            -
            ```
         | 
| 70 75 |  | 
| 71 | 
            -
            3. Run patched pgpool-II:
         | 
| 72 | 
            -
            ```
         | 
| 76 | 
            +
            # 3. Run patched pgpool-II:
         | 
| 73 77 | 
             
            $ prestogres -D pgdata pgpool
         | 
| 74 | 
            -
            ```
         | 
| 75 78 |  | 
| 76 | 
            -
            4. Run PostgreSQL:
         | 
| 77 | 
            -
            ```
         | 
| 79 | 
            +
            # 4. Run PostgreSQL:
         | 
| 78 80 | 
             
            $ prestogres -D pgdata pg_ctl start
         | 
| 79 | 
            -
            ```
         | 
| 80 81 |  | 
| 81 | 
            -
            5. Finally, you can connect to pgpool-II using `psql` command:
         | 
| 82 | 
            -
            ```
         | 
| 82 | 
            +
            # 5. Finally, you can connect to pgpool-II using `psql` command:
         | 
| 83 83 | 
             
            $ psql -h localhost -p 9900 -U pg postgres
         | 
| 84 | 
            +
            > SELECT * FROM sys.node;
         | 
| 84 85 | 
             
            ```
         | 
| 85 86 |  | 
| 86 87 | 
             
            If configuration is correct, you can run `SELECT * FROM sys.node;` query. Otherwise, see log files in **./pgdata/log/** directory.
         | 
| @@ -111,7 +112,6 @@ Following parameters are unique to Prestogres: | |
| 111 112 |  | 
| 112 113 | 
             
            * **presto_server**: Default address:port of Presto server.
         | 
| 113 114 | 
             
            * **presto_catalog**: Default catalog (connector) name of Presto such as `hive-cdh4`, `hive-hadoop1`, etc.
         | 
| 114 | 
            -
            * **presto_schema**: Default schema name of Presto. You can read other schemas by qualified name like `FROM myschema.table1`
         | 
| 115 115 | 
             
            * **presto_external_auth_prog**: Default path to an external authentication program used by `prestogres_external` authentication moethd. See following Authentication section for details.
         | 
| 116 116 |  | 
| 117 117 | 
             
            You can overwrite these parameters for each connecting users. See also following *pool_hba.conf* section.
         | 
| @@ -124,10 +124,10 @@ See [sample pool_hba.conf file](https://github.com/treasure-data/prestogres/blob | |
| 124 124 |  | 
| 125 125 | 
             
            ```conf
         | 
| 126 126 | 
             
            # TYPE   DATABASE   USER   CIDR-ADDRESS                  METHOD                OPTIONS
         | 
| 127 | 
            -
            host      | 
| 128 | 
            -
            host      | 
| 129 | 
            -
            host     altdb      pg     0.0.0.0/0                     prestogres_md5        server:localhost:8190, | 
| 130 | 
            -
            host     all        all    0.0.0.0/0                     prestogres_external   auth_prog:/opt/prestogres/auth.py
         | 
| 127 | 
            +
            host     postgres   pg     127.0.0.1/32                  trust
         | 
| 128 | 
            +
            host     postgres   pg     127.0.0.1/32,192.168.0.0/16   prestogres_md5
         | 
| 129 | 
            +
            host     altdb      pg     0.0.0.0/0                     prestogres_md5        server:localhost:8190,pg_database:postgres
         | 
| 130 | 
            +
            host     all        all    0.0.0.0/0                     prestogres_external   auth_prog:/opt/prestogres/auth.py,pg_database:postgres,pg_user:pg
         | 
| 131 131 | 
             
            ```
         | 
| 132 132 |  | 
| 133 133 | 
             
            See also *Creating database* section.
         | 
| @@ -145,8 +145,8 @@ In pool_hba.conf file, you can set following options to OPTIONS field: | |
| 145 145 |  | 
| 146 146 | 
             
            * **server**: Address:port of Presto server, which overwrites `presto_servers` parameter in pgpool.conf.
         | 
| 147 147 | 
             
            * **catalog**: Catalog (connector) name of Presto, which overwrites `presto_catalog` parameter in pgpool.conf.
         | 
| 148 | 
            -
            * **schema**:  | 
| 149 | 
            -
            * **user**: User name to run queries on Presto. By default, Prestogres uses the same user name used to login to pgpool-II.
         | 
| 148 | 
            +
            * **schema**: Default schema name of Presto. By default, Prestogres uses the same name with the database name used to login to pgpool-II. Following `pg_database` parameter doesn't overwrite affect this parameter.
         | 
| 149 | 
            +
            * **user**: User name to run queries on Presto. By default, Prestogres uses the same user name used to login to pgpool-II. Following `pg_user` parameter doesn't overwrite affect this parameter.
         | 
| 150 150 | 
             
            * **pg_database**: Overwrite database to connect to PostgreSQL.
         | 
| 151 151 | 
             
            * **pg_user**: Overwrite user name to connect to PostgreSQL.
         | 
| 152 152 |  | 
| @@ -223,7 +223,7 @@ commands: | |
| 223 223 |  | 
| 224 224 | 
             
            ## Development
         | 
| 225 225 |  | 
| 226 | 
            -
            To install git HEAD, use following  | 
| 226 | 
            +
            To install git HEAD, use following commands to build:
         | 
| 227 227 |  | 
| 228 228 | 
             
            ```sh
         | 
| 229 229 | 
             
            # 1. clone prestogres repository:
         | 
| @@ -239,7 +239,6 @@ $ bundle | |
| 239 239 | 
             
            $ bundle exec rake
         | 
| 240 240 |  | 
| 241 241 | 
             
            # 4. install the created package:
         | 
| 242 | 
            -
            $ gem install --no-ri --no-rdoc pkg/prestogres | 
| 242 | 
            +
            $ gem install --no-ri --no-rdoc pkg/prestogres-*.gem
         | 
| 243 243 | 
             
            # if this command failed, you may need to install toolchain (gcc, etc.) to build pgpool-II
         | 
| 244 244 | 
             
            ```
         | 
| 245 | 
            -
             | 
    
        data/Rakefile
    CHANGED
    
    | @@ -4,9 +4,10 @@ Bundler::GemHelper.install_tasks | |
| 4 4 | 
             
            require 'rake/extensiontask'
         | 
| 5 5 |  | 
| 6 6 | 
             
            spec = eval File.read("prestogres.gemspec")
         | 
| 7 | 
            -
            Rake::ExtensionTask.new(' | 
| 7 | 
            +
            Rake::ExtensionTask.new('prestogres_config', spec) do |ext|
         | 
| 8 8 | 
             
              ext.cross_compile = true
         | 
| 9 | 
            -
              ext.lib_dir =  | 
| 9 | 
            +
              ext.lib_dir = 'lib'
         | 
| 10 | 
            +
              ext.ext_dir = 'ext'
         | 
| 10 11 | 
             
              #ext.cross_platform = 'i386-mswin32'
         | 
| 11 12 | 
             
            end
         | 
| 12 13 |  | 
    
        data/VERSION
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            0. | 
| 1 | 
            +
            0.3.0
         | 
    
        data/bin/prestogres
    CHANGED
    
    | @@ -7,7 +7,7 @@ config = { | |
| 7 7 | 
             
            }
         | 
| 8 8 |  | 
| 9 9 | 
             
            def usage(error=nil)
         | 
| 10 | 
            -
              puts "usage: #{File.basename($0)} -D <data dir> <command>"
         | 
| 10 | 
            +
              puts "usage: #{File.basename($0)} -D <data dir> [-P <postgresql bin path>] <command>"
         | 
| 11 11 | 
             
              puts "commands:"
         | 
| 12 12 | 
             
              puts "  setup                 setup <data dir>"
         | 
| 13 13 | 
             
              puts "  pgpool                start pgpool as a daemon process"
         | 
| @@ -38,6 +38,8 @@ ARGV.each_with_index do |a,i| | |
| 38 38 | 
             
              case a
         | 
| 39 39 | 
             
              when "-D"
         | 
| 40 40 | 
             
                config_key = :data_dir
         | 
| 41 | 
            +
              when "-P"
         | 
| 42 | 
            +
                config_key = :bin_path
         | 
| 41 43 | 
             
              when "-h", "-?", "--help"
         | 
| 42 44 | 
             
                config[:command] = :help
         | 
| 43 45 | 
             
              when "setup"
         | 
| @@ -73,6 +75,8 @@ setup_params = { | |
| 73 75 | 
             
             unix_socket_directory: nil,
         | 
| 74 76 | 
             
            }
         | 
| 75 77 |  | 
| 78 | 
            +
            ENV['PATH'] = "#{ENV['PATH']}:#{config[:bin_path]}"
         | 
| 79 | 
            +
             | 
| 76 80 | 
             
            case config[:command]
         | 
| 77 81 | 
             
            when :help
         | 
| 78 82 | 
             
              usage nil
         | 
| @@ -87,15 +91,11 @@ when :setup | |
| 87 91 |  | 
| 88 92 | 
             
              require "erb"
         | 
| 89 93 | 
             
              require "fileutils"
         | 
| 94 | 
            +
              require "shellwords"
         | 
| 90 95 |  | 
| 91 | 
            -
              def  | 
| 92 | 
            -
                 | 
| 93 | 
            -
             | 
| 94 | 
            -
                  system *cmdline
         | 
| 95 | 
            -
                else
         | 
| 96 | 
            -
                  puts "setup> #{cmdline}"
         | 
| 97 | 
            -
                  system cmdline
         | 
| 98 | 
            -
                end
         | 
| 96 | 
            +
              def setup_cmd(cmdline)
         | 
| 97 | 
            +
                puts "setup> #{cmdline}"
         | 
| 98 | 
            +
                system cmdline
         | 
| 99 99 | 
             
                unless $?.success?
         | 
| 100 100 | 
             
                  puts "******************"
         | 
| 101 101 | 
             
                  puts "** setup failed **"
         | 
| @@ -114,44 +114,84 @@ when :setup | |
| 114 114 | 
             
                end
         | 
| 115 115 | 
             
              end
         | 
| 116 116 |  | 
| 117 | 
            +
              def se(raw)
         | 
| 118 | 
            +
                Shellwords.escape(raw)
         | 
| 119 | 
            +
              end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
              `which initdb && which postgres`
         | 
| 122 | 
            +
              unless $?.success?
         | 
| 123 | 
            +
                puts ""
         | 
| 124 | 
            +
                puts "Can't find initdb or postgres command. Check following items:"
         | 
| 125 | 
            +
                puts ""
         | 
| 126 | 
            +
                puts "  * You need to install PostgreSQL server. Use apt or yum to install postgresql package."
         | 
| 127 | 
            +
                puts "  * You need to set -P option to specify path to the commands. Example:"
         | 
| 128 | 
            +
                puts ""
         | 
| 129 | 
            +
                puts "    $ prestogres -D data_dir -P /usr/lib/postgresql/9.1/bin setup"
         | 
| 130 | 
            +
                puts ""
         | 
| 131 | 
            +
                exit 1
         | 
| 132 | 
            +
              end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
              # src files
         | 
| 117 135 | 
             
              config_src_dir = File.join(File.dirname(__FILE__), "..", "config")
         | 
| 136 | 
            +
              postgresql_conf_path = File.join(config_src_dir, "postgresql.conf")
         | 
| 118 137 | 
             
              pgsql_dir = File.join(File.dirname(__FILE__), "..", "pgsql")
         | 
| 138 | 
            +
              setup_sql_path = File.join(pgsql_dir, "setup.sql")
         | 
| 119 139 |  | 
| 120 140 | 
             
              puts "Setting up '#{config[:data_dir]}'..."
         | 
| 121 141 | 
             
              data_dir = File.expand_path(config[:data_dir])
         | 
| 122 142 |  | 
| 123 | 
            -
              @config = setup_params  # used by erb files
         | 
| 124 | 
            -
              @config[:pgpool_pid_file] = File.join(data_dir, "run", "pgpool.pid")
         | 
| 125 | 
            -
              @config[:pgpool_status_dir] = File.join(data_dir, "run")
         | 
| 126 | 
            -
              @config[:unix_socket_directory] = File.join(data_dir, "run")
         | 
| 127 | 
            -
             | 
| 128 143 | 
             
              # log & socket dirs
         | 
| 129 | 
            -
               | 
| 130 | 
            -
               | 
| 144 | 
            +
              log_dir = File.join(data_dir, "log")
         | 
| 145 | 
            +
              run_dir = File.join(data_dir, "run")
         | 
| 146 | 
            +
              FileUtils.mkdir_p log_dir
         | 
| 147 | 
            +
              FileUtils.mkdir_p run_dir
         | 
| 148 | 
            +
             | 
| 149 | 
            +
              pgpool_dir = File.join(data_dir, "pgpool")
         | 
| 150 | 
            +
              postgres_dir = File.join(data_dir, "postgres")
         | 
| 151 | 
            +
             | 
| 152 | 
            +
              @config = setup_params  # used by erb files
         | 
| 153 | 
            +
              @config[:pgpool_pid_file] = File.join(run_dir, "pgpool.pid")
         | 
| 154 | 
            +
              @config[:pgpool_status_dir] = run_dir
         | 
| 155 | 
            +
              @config[:unix_socket_directory] = run_dir
         | 
| 131 156 |  | 
| 132 157 | 
             
              # pgpool
         | 
| 133 | 
            -
              FileUtils.mkdir_p  | 
| 158 | 
            +
              FileUtils.mkdir_p pgpool_dir
         | 
| 134 159 | 
             
              %w[pcp.conf.sample pgpool.conf pool_hba.conf pool_passwd].each do |fname|
         | 
| 135 | 
            -
                 | 
| 136 | 
            -
             | 
| 160 | 
            +
                # run ERB for each config files
         | 
| 161 | 
            +
                dst_path = File.join(pgpool_dir, fname)
         | 
| 162 | 
            +
                src_path = File.join(config_src_dir, fname)
         | 
| 163 | 
            +
                File.open(dst_path, "w") {|f|
         | 
| 164 | 
            +
                  f.write ERB.new(File.read(src_path)).result
         | 
| 137 165 | 
             
                }
         | 
| 138 166 | 
             
              end
         | 
| 139 167 |  | 
| 140 168 | 
             
              # postgresql
         | 
| 141 | 
            -
               | 
| 169 | 
            +
              # 1. initdb postgres_dir
         | 
| 170 | 
            +
              setup_cmd "initdb -U pg --no-locale -E UNICODE #{se(postgres_dir)}"
         | 
| 142 171 | 
             
              File.open(File.join(data_dir, "postgres", "postgresql.conf"), "a") {|f|
         | 
| 143 | 
            -
                f.write ERB.new(File.read( | 
| 172 | 
            +
                f.write ERB.new(File.read(postgresql_conf_path)).result
         | 
| 144 173 | 
             
              }
         | 
| 145 174 |  | 
| 146 | 
            -
              #  | 
| 147 | 
            -
               | 
| 175 | 
            +
              # 2. postgres -D postgres_dir -c listen_addresses=
         | 
| 176 | 
            +
              # start postgres without listening on TCP
         | 
| 177 | 
            +
              postgres_cmd = "postgres -D #{se(postgres_dir)} -c listen_addresses="
         | 
| 178 | 
            +
              puts "setup> #{postgres_cmd}"
         | 
| 179 | 
            +
              pid = spawn postgres_cmd
         | 
| 180 | 
            +
             | 
| 181 | 
            +
              # 3. psql < pgsql/setup.sql
         | 
| 148 182 | 
             
              begin
         | 
| 149 | 
            -
                 | 
| 183 | 
            +
                # waits for spinup of postgres
         | 
| 184 | 
            +
                sleep 2
         | 
| 185 | 
            +
                puts "initializing database..."
         | 
| 186 | 
            +
                sleep 8
         | 
| 150 187 |  | 
| 151 | 
            -
                 | 
| 188 | 
            +
                psql_cmd = "psql -h #{se(@config[:unix_socket_directory])} -p #{@config[:backend_port]} -U pg postgres"
         | 
| 189 | 
            +
                setup_cmd "#{psql_cmd} < #{se(setup_sql_path)}"
         | 
| 152 190 | 
             
              ensure
         | 
| 153 | 
            -
                 | 
| 191 | 
            +
                # 4. shutdown postgres
         | 
| 192 | 
            +
                Process.kill(:SIGQUIT, pid)
         | 
| 154 193 | 
             
              end
         | 
| 194 | 
            +
              Process.waitpid(pid)
         | 
| 155 195 |  | 
| 156 196 | 
             
              puts <<EOF
         | 
| 157 197 |  | 
| @@ -203,7 +243,9 @@ when :passwd | |
| 203 243 | 
             
              binary = File.join(prefix, "bin", 'pg_md5')
         | 
| 204 244 |  | 
| 205 245 | 
             
              data_dir = config[:data_dir]
         | 
| 206 | 
            -
               | 
| 246 | 
            +
              pgpool_conf_path = File.join(data_dir, "pgpool", "pgpool.conf")
         | 
| 247 | 
            +
             | 
| 248 | 
            +
              args = ["-f", pgpool_conf_path, "-p", "-m", "-u"].concat(args)
         | 
| 207 249 |  | 
| 208 250 | 
             
              puts "#{binary} #{args.join(' ')}"
         | 
| 209 251 | 
             
              system binary, *args
         | 
    
        data/config/postgresql.conf
    CHANGED
    
    | @@ -1,2 +1,2 @@ | |
| 1 1 | 
             
            port = <%= @config[:backend_port] %>
         | 
| 2 | 
            -
             | 
| 2 | 
            +
            unix_socket_directories = '<%= @config[:unix_socket_directory] %>'
         | 
    
        data/ext/depend
    CHANGED
    
    | @@ -1,8 +1,16 @@ | |
| 1 1 | 
             
            # vim: ft=make noexpandtab
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 3 | 
            +
            # normalize rubyarchdir which is not available depending on rake or gem
         | 
| 4 | 
            +
            narchdir = $(if $(rubyarchdir),$(rubyarchdir),$(RUBYARCHDIR))
         | 
| 4 5 |  | 
| 5 | 
            -
             | 
| 6 | 
            +
            # hack for RubyGems >= 1.8.26
         | 
| 7 | 
            +
            final_archdir = $(if $(findstring .gem.,$(narchdir)),$(dir $(narchdir)),$(narchdir))
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            INSTALL_DATA = $(realpath $(final_archdir))/prestogres
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            PGPOOL2_PATH = $(realpath $(srcdir)/../pgpool2)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            CFLAGS += -DPRESTOGRES_PREFIX="\"$(INSTALL_DATA)\""
         | 
| 6 14 |  | 
| 7 15 | 
             
            all: pgpool2
         | 
| 8 16 |  | 
| @@ -12,10 +20,10 @@ install: install-pgpool2 | |
| 12 20 |  | 
| 13 21 | 
             
            pgpool2:
         | 
| 14 22 | 
             
            	mkdir -p build
         | 
| 15 | 
            -
            	cd build &&  | 
| 16 | 
            -
            		CFLAGS="-I$( | 
| 23 | 
            +
            	cd build && "$(PGPOOL2_PATH)/configure" \
         | 
| 24 | 
            +
            		CFLAGS="-I$(PGPOOL2_PATH)" \
         | 
| 17 25 | 
             
            		--with-openssl \
         | 
| 18 | 
            -
            		--prefix="$( | 
| 26 | 
            +
            		--prefix="$(INSTALL_DATA)"
         | 
| 19 27 | 
             
            	cd build && make sysconfdir=/opt/prestogres/etc
         | 
| 20 28 |  | 
| 21 29 | 
             
            clean-pgpool2:
         | 
    
        data/pgpool2/child.c
    CHANGED
    
    | @@ -295,6 +295,9 @@ void do_child(int unix_fd, int inet_fd) | |
| 295 295 | 
             
            			goto retry_startup;
         | 
| 296 296 | 
             
            		}
         | 
| 297 297 |  | 
| 298 | 
            +
            		/* this should run before ClientAuthentication */
         | 
| 299 | 
            +
            		pool_prestogres_set_defaults(sp);
         | 
| 300 | 
            +
             | 
| 298 301 | 
             
            		if (pool_config->enable_pool_hba)
         | 
| 299 302 | 
             
            		{
         | 
| 300 303 | 
             
            			/*
         | 
| @@ -332,9 +335,6 @@ void do_child(int unix_fd, int inet_fd) | |
| 332 335 | 
             
            			}
         | 
| 333 336 | 
             
            		}
         | 
| 334 337 |  | 
| 335 | 
            -
            		/* this should run after ClientAuthentication */
         | 
| 336 | 
            -
            		pool_prestogres_init_session(frontend);
         | 
| 337 | 
            -
             | 
| 338 338 | 
             
            		/*
         | 
| 339 339 | 
             
            		 * Ok, negotiation with frontend has been done. Let's go to the
         | 
| 340 340 | 
             
            		 * next step.  Connect to backend if there's no existing
         | 
    
        data/pgpool2/pool.h
    CHANGED
    
    | @@ -652,6 +652,6 @@ extern const char* presto_external_auth_prog; | |
| 652 652 | 
             
            int send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt);
         | 
| 653 653 | 
             
            int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, 	char *password, int *pwdSize);
         | 
| 654 654 |  | 
| 655 | 
            -
            void  | 
| 655 | 
            +
            void pool_prestogres_set_defaults(StartupPacket *sp);
         | 
| 656 656 |  | 
| 657 657 | 
             
            #endif /* POOL_H */
         | 
    
        data/pgpool2/pool_config.c
    CHANGED
    
    | @@ -1896,7 +1896,6 @@ int pool_init_config(void) | |
| 1896 1896 |  | 
| 1897 1897 | 
             
            	pool_config->presto_server = "";
         | 
| 1898 1898 | 
             
            	pool_config->presto_catalog = "";
         | 
| 1899 | 
            -
            	pool_config->presto_schema = "default";
         | 
| 1900 1899 | 
             
            	pool_config->presto_external_auth_prog = NULL;
         | 
| 1901 1900 |  | 
| 1902 1901 | 
             
            	pool_config->replication_mode = 0;
         | 
| @@ -2599,24 +2598,6 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context) | |
| 2599 2598 | 
             
            			}
         | 
| 2600 2599 | 
             
            			pool_config->presto_catalog = str;
         | 
| 2601 2600 | 
             
            		}
         | 
| 2602 | 
            -
            		else if (!strcmp(key, "presto_schema") && CHECK_CONTEXT(INIT_CONFIG, context))
         | 
| 2603 | 
            -
            		{
         | 
| 2604 | 
            -
            			char *str;
         | 
| 2605 | 
            -
             | 
| 2606 | 
            -
            			if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
         | 
| 2607 | 
            -
            			{
         | 
| 2608 | 
            -
            				PARSE_ERROR();
         | 
| 2609 | 
            -
            				fclose(fd);
         | 
| 2610 | 
            -
            				return(-1);
         | 
| 2611 | 
            -
            			}
         | 
| 2612 | 
            -
            			str = extract_string(yytext, token);
         | 
| 2613 | 
            -
            			if (str == NULL)
         | 
| 2614 | 
            -
            			{
         | 
| 2615 | 
            -
            				fclose(fd);
         | 
| 2616 | 
            -
            				return(-1);
         | 
| 2617 | 
            -
            			}
         | 
| 2618 | 
            -
            			pool_config->presto_schema = str;
         | 
| 2619 | 
            -
            		}
         | 
| 2620 2601 | 
             
            		else if (!strcmp(key, "presto_external_auth_prog") && CHECK_CONTEXT(INIT_CONFIG, context))
         | 
| 2621 2602 | 
             
            		{
         | 
| 2622 2603 | 
             
            			char *str;
         | 
    
        data/pgpool2/pool_hba.c
    CHANGED
    
    | @@ -1709,23 +1709,23 @@ static POOL_STATUS pool_prestogres_hba_auth_external(POOL_CONNECTION *frontend) | |
| 1709 1709 | 
             
            	return POOL_CONTINUE;
         | 
| 1710 1710 | 
             
            }
         | 
| 1711 1711 |  | 
| 1712 | 
            -
            void  | 
| 1712 | 
            +
            void pool_prestogres_set_defaults(StartupPacket *sp)
         | 
| 1713 1713 | 
             
            {
         | 
| 1714 1714 | 
             
                if (presto_server == NULL) {
         | 
| 1715 1715 | 
             
                    presto_server = pool_config->presto_server;
         | 
| 1716 1716 | 
             
                }
         | 
| 1717 1717 | 
             
                if (presto_user == NULL) {
         | 
| 1718 | 
            -
                    presto_user =  | 
| 1718 | 
            +
                    presto_user = strdup(sp->user);
         | 
| 1719 1719 | 
             
                }
         | 
| 1720 1720 | 
             
                if (presto_catalog == NULL) {
         | 
| 1721 1721 | 
             
                    presto_catalog = pool_config->presto_catalog;
         | 
| 1722 1722 | 
             
                }
         | 
| 1723 1723 | 
             
                if (presto_schema == NULL) {
         | 
| 1724 | 
            -
                    presto_schema =  | 
| 1724 | 
            +
                    presto_schema = strdup(sp->database);
         | 
| 1725 1725 | 
             
                }
         | 
| 1726 | 
            -
                pool_debug(" | 
| 1727 | 
            -
                pool_debug(" | 
| 1728 | 
            -
                pool_debug(" | 
| 1729 | 
            -
                pool_debug(" | 
| 1726 | 
            +
                pool_debug("pool_prestogres_set_defaults: presto_server: %s", presto_server);
         | 
| 1727 | 
            +
                pool_debug("pool_prestogres_set_defaults: presto_user: %s", presto_user);
         | 
| 1728 | 
            +
                pool_debug("pool_prestogres_set_defaults: presto_catalog: %s", presto_catalog);
         | 
| 1729 | 
            +
                pool_debug("pool_prestogres_set_defaults: presto_schema: %s", presto_schema);
         | 
| 1730 1730 | 
             
            }
         | 
| 1731 1731 |  | 
| @@ -404,7 +404,31 @@ static void run_and_rewrite_system_catalog_query(POOL_SESSION_CONTEXT* session_c | |
| 404 404 | 
             
            	POOL_CONNECTION_POOL *backend = session_context->backend;
         | 
| 405 405 | 
             
            	con = CONNECTION(backend, session_context->load_balance_node_id);
         | 
| 406 406 |  | 
| 407 | 
            -
            	/* build query */
         | 
| 407 | 
            +
            	/* build SET query */
         | 
| 408 | 
            +
            	buffer = rewrite_query_string_buffer;
         | 
| 409 | 
            +
            	bufend = buffer + sizeof(rewrite_query_string_buffer);
         | 
| 410 | 
            +
             | 
| 411 | 
            +
            	buffer = strcpy_capped(buffer, bufend - buffer, "set search_path to E'");
         | 
| 412 | 
            +
            	buffer = strcpy_capped_escaped(buffer, bufend - buffer, presto_schema, "'\\");
         | 
| 413 | 
            +
            	buffer = strcpy_capped(buffer, bufend - buffer, "'");
         | 
| 414 | 
            +
             | 
| 415 | 
            +
            	if (buffer == NULL) {
         | 
| 416 | 
            +
            		rewrite_error_query(query_context, "schema name too long", NULL);
         | 
| 417 | 
            +
            		return;
         | 
| 418 | 
            +
            	}
         | 
| 419 | 
            +
             | 
| 420 | 
            +
            	/* run SET query */
         | 
| 421 | 
            +
            	status = do_query_or_get_error_message(con,
         | 
| 422 | 
            +
            			rewrite_query_string_buffer, &res, MAJOR(backend), &errmsg, &errcode);
         | 
| 423 | 
            +
            	free_select_result(res);
         | 
| 424 | 
            +
             | 
| 425 | 
            +
            	if (errmsg != NULL) {
         | 
| 426 | 
            +
            		rewrite_error_query(query_context, errmsg, errcode);
         | 
| 427 | 
            +
            	} else if (status != POOL_CONTINUE) {
         | 
| 428 | 
            +
            		rewrite_error_query(query_context, "Unknown execution error", NULL);
         | 
| 429 | 
            +
            	}
         | 
| 430 | 
            +
             | 
| 431 | 
            +
            	/* build run_system_catalog_as_temp_table query */
         | 
| 408 432 | 
             
            	buffer = rewrite_query_string_buffer;
         | 
| 409 433 | 
             
            	bufend = buffer + sizeof(rewrite_query_string_buffer);
         | 
| 410 434 |  | 
| @@ -415,6 +439,8 @@ static void run_and_rewrite_system_catalog_query(POOL_SESSION_CONTEXT* session_c | |
| 415 439 | 
             
            	buffer = strcpy_capped(buffer, bufend - buffer, "', E'");
         | 
| 416 440 | 
             
            	buffer = strcpy_capped_escaped(buffer, bufend - buffer, presto_catalog, "'\\");
         | 
| 417 441 | 
             
            	buffer = strcpy_capped(buffer, bufend - buffer, "', E'");
         | 
| 442 | 
            +
            	buffer = strcpy_capped_escaped(buffer, bufend - buffer, presto_schema, "'\\");
         | 
| 443 | 
            +
            	buffer = strcpy_capped(buffer, bufend - buffer, "', E'");
         | 
| 418 444 | 
             
            	buffer = strcpy_capped_escaped(buffer, bufend - buffer, PRESTO_RESULT_TABLE_NAME, "'\\");
         | 
| 419 445 | 
             
            	buffer = strcpy_capped(buffer, bufend - buffer, "', E'");
         | 
| 420 446 | 
             
            	buffer = strcpy_capped_escaped(buffer, bufend - buffer, query_context->original_query, "'\\");
         | 
| @@ -425,7 +451,7 @@ static void run_and_rewrite_system_catalog_query(POOL_SESSION_CONTEXT* session_c | |
| 425 451 | 
             
            		return;
         | 
| 426 452 | 
             
            	}
         | 
| 427 453 |  | 
| 428 | 
            -
            	/* run query */
         | 
| 454 | 
            +
            	/* run run_system_catalog_as_temp_table query */
         | 
| 429 455 | 
             
            	status = do_query_or_get_error_message(con,
         | 
| 430 456 | 
             
            			rewrite_query_string_buffer, &res, MAJOR(backend), &errmsg, &errcode);
         | 
| 431 457 | 
             
            	free_select_result(res);
         | 
    
        data/pgsql/prestogres.py
    CHANGED
    
    | @@ -6,7 +6,7 @@ import time | |
| 6 6 | 
             
            # convert Presto query result type to PostgreSQL type
         | 
| 7 7 | 
             
            def _pg_result_type(presto_type):
         | 
| 8 8 | 
             
                if presto_type == "varchar":
         | 
| 9 | 
            -
                    return " | 
| 9 | 
            +
                    return "varchar(255)"
         | 
| 10 10 | 
             
                elif presto_type == "bigint":
         | 
| 11 11 | 
             
                    return "bigint"
         | 
| 12 12 | 
             
                elif presto_type == "boolean":
         | 
| @@ -19,7 +19,7 @@ def _pg_result_type(presto_type): | |
| 19 19 | 
             
            # convert Presto type to PostgreSQL type
         | 
| 20 20 | 
             
            def _pg_table_type(presto_type):
         | 
| 21 21 | 
             
                if presto_type == "varchar":
         | 
| 22 | 
            -
                    return "varchar( | 
| 22 | 
            +
                    return "varchar(255)"
         | 
| 23 23 | 
             
                elif presto_type == "bigint":
         | 
| 24 24 | 
             
                    return "bigint"
         | 
| 25 25 | 
             
                elif presto_type == "boolean":
         | 
| @@ -30,7 +30,7 @@ def _pg_table_type(presto_type): | |
| 30 30 | 
             
                    raise Exception("unknown table column type: " + plpy.quote_ident(presto_type))
         | 
| 31 31 |  | 
| 32 32 | 
             
            # build CREATE TEMPORARY TABLE statement
         | 
| 33 | 
            -
            def _build_create_temp_table_sql(table_name, column_names, column_types | 
| 33 | 
            +
            def _build_create_temp_table_sql(table_name, column_names, column_types):
         | 
| 34 34 | 
             
                create_sql = "create temporary table %s (\n  " % plpy.quote_ident(table_name)
         | 
| 35 35 |  | 
| 36 36 | 
             
                first = True
         | 
| @@ -44,9 +44,26 @@ def _build_create_temp_table_sql(table_name, column_names, column_types, not_nul | |
| 44 44 | 
             
                    create_sql += " "
         | 
| 45 45 | 
             
                    create_sql += column_type
         | 
| 46 46 |  | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 47 | 
            +
                create_sql += "\n)"
         | 
| 48 | 
            +
                return create_sql
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            # build CREATE TABLE statement
         | 
| 51 | 
            +
            def _build_create_table_sql(schema_name, table_name, column_names, column_types, not_nulls):
         | 
| 52 | 
            +
                create_sql = "create table %s.%s (\n  " % (plpy.quote_ident(schema_name), plpy.quote_ident(table_name))
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                first = True
         | 
| 55 | 
            +
                for column_name, column_type, not_null in zip(column_names, column_types, not_nulls):
         | 
| 56 | 
            +
                    if first:
         | 
| 57 | 
            +
                        first = False
         | 
| 58 | 
            +
                    else:
         | 
| 59 | 
            +
                        create_sql += ",\n  "
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                    create_sql += plpy.quote_ident(column_name)
         | 
| 62 | 
            +
                    create_sql += " "
         | 
| 63 | 
            +
                    create_sql += column_type
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                    if not_null:
         | 
| 66 | 
            +
                        create_sql += " not null"
         | 
| 50 67 |  | 
| 51 68 | 
             
                create_sql += "\n)"
         | 
| 52 69 | 
             
                return create_sql
         | 
| @@ -100,21 +117,28 @@ class SchemaCache(object): | |
| 100 117 | 
             
                    self.server = None
         | 
| 101 118 | 
             
                    self.user = None
         | 
| 102 119 | 
             
                    self.catalog = None
         | 
| 120 | 
            +
                    self.schema = None
         | 
| 103 121 | 
             
                    self.schema_names = None
         | 
| 104 122 | 
             
                    self.statements = None
         | 
| 105 123 | 
             
                    self.expire_time = None
         | 
| 124 | 
            +
                    self.query_cache = {}
         | 
| 106 125 |  | 
| 107 | 
            -
                def is_cached(self, server, user, catalog, current_time):
         | 
| 108 | 
            -
                    return self.server == server and self.user == user  | 
| 126 | 
            +
                def is_cached(self, server, user, catalog, schema, current_time):
         | 
| 127 | 
            +
                    return self.server == server and self.user == user \
         | 
| 128 | 
            +
                           and self.catalog == catalog and self.schema == schema \
         | 
| 109 129 | 
             
                           and self.statements is not None and current_time < self.expire_time
         | 
| 110 130 |  | 
| 111 | 
            -
                def set_cache(self, server, user, catalog, schema_names, statements, expire_time):
         | 
| 131 | 
            +
                def set_cache(self, server, user, catalog, schema, schema_names, statements, expire_time):
         | 
| 112 132 | 
             
                    self.server = server
         | 
| 113 133 | 
             
                    self.user = user
         | 
| 114 134 | 
             
                    self.catalog = catalog
         | 
| 135 | 
            +
                    self.schema = schema
         | 
| 115 136 | 
             
                    self.schema_names = schema_names
         | 
| 116 137 | 
             
                    self.statements = statements
         | 
| 117 138 | 
             
                    self.expire_time = expire_time
         | 
| 139 | 
            +
                    self.query_cache = {}
         | 
| 140 | 
            +
             | 
| 141 | 
            +
            QueryResult = namedtuple("QueryResult", ("column_names", "column_types", "result"))
         | 
| 118 142 |  | 
| 119 143 | 
             
            OidToTypeNameMapping = {}
         | 
| 120 144 |  | 
| @@ -171,14 +195,15 @@ def run_presto_as_temp_table(server, user, catalog, schema, result_table, query) | |
| 171 195 | 
             
                    e.__class__.__module__ = "__main__"
         | 
| 172 196 | 
             
                    raise
         | 
| 173 197 |  | 
| 174 | 
            -
            def run_system_catalog_as_temp_table(server, user, catalog, result_table, query):
         | 
| 198 | 
            +
            def run_system_catalog_as_temp_table(server, user, catalog, schema, result_table, query):
         | 
| 175 199 | 
             
                try:
         | 
| 176 | 
            -
                    client = presto_client.Client(server=server, user=user, catalog=catalog, schema= | 
| 200 | 
            +
                    client = presto_client.Client(server=server, user=user, catalog=catalog, schema=schema)
         | 
| 177 201 |  | 
| 178 202 | 
             
                    # create SQL statements which put data to system catalogs
         | 
| 179 | 
            -
                    if SchemaCacheEntry.is_cached(server, user, catalog, time.time()):
         | 
| 203 | 
            +
                    if SchemaCacheEntry.is_cached(server, user, catalog, schema, time.time()):
         | 
| 180 204 | 
             
                        schema_names = SchemaCacheEntry.schema_names
         | 
| 181 205 | 
             
                        statements = SchemaCacheEntry.statements
         | 
| 206 | 
            +
                        query_cache = SchemaCacheEntry.query_cache
         | 
| 182 207 |  | 
| 183 208 | 
             
                    else:
         | 
| 184 209 | 
             
                        # get table list
         | 
| @@ -223,57 +248,69 @@ def run_system_catalog_as_temp_table(server, user, catalog, result_table, query) | |
| 223 248 | 
             
                                    column_types.append(_pg_table_type(column.type))
         | 
| 224 249 | 
             
                                    not_nulls.append(not column.nullable)
         | 
| 225 250 |  | 
| 226 | 
            -
                                create_sql =  | 
| 251 | 
            +
                                create_sql = _build_create_table_sql(schema_name, table_name, column_names, column_types, not_nulls)
         | 
| 227 252 | 
             
                                statements.append(create_sql)
         | 
| 228 253 |  | 
| 229 | 
            -
                        # cache expires after  | 
| 230 | 
            -
                        SchemaCacheEntry.set_cache(server, user, catalog, schema_names, statements, time.time() +  | 
| 254 | 
            +
                        # cache expires after 60 seconds
         | 
| 255 | 
            +
                        SchemaCacheEntry.set_cache(server, user, catalog, schema, schema_names, statements, time.time() + 60)
         | 
| 256 | 
            +
                        query_cache = {}
         | 
| 231 257 |  | 
| 232 | 
            -
                     | 
| 233 | 
            -
                    subxact = plpy.subtransaction()
         | 
| 234 | 
            -
                    subxact.enter()
         | 
| 235 | 
            -
                    try:
         | 
| 236 | 
            -
                        # delete all schemas excepting prestogres_catalog
         | 
| 237 | 
            -
                        sql = "select n.nspname as schema_name from pg_catalog.pg_namespace n" \
         | 
| 238 | 
            -
                              " where n.nspname not in ('prestogres_catalog', 'pg_catalog', 'information_schema', 'public')" \
         | 
| 239 | 
            -
                              " and n.nspname !~ '^pg_toast'"
         | 
| 240 | 
            -
                        for row in plpy.cursor(sql):
         | 
| 241 | 
            -
                            plpy.execute("drop schema %s cascade" % plpy.quote_ident(row["schema_name"]))
         | 
| 242 | 
            -
             | 
| 243 | 
            -
                        # delete all tables in prestogres_catalog
         | 
| 244 | 
            -
                        # relkind = 'r' takes only tables and skip views, indexes, etc.
         | 
| 245 | 
            -
                        sql = "select n.nspname as schema_name, c.relname as table_name from pg_catalog.pg_class c" \
         | 
| 246 | 
            -
                              " left join pg_catalog.pg_namespace n on n.oid = c.relnamespace" \
         | 
| 247 | 
            -
                              " where c.relkind in ('r')" \
         | 
| 248 | 
            -
                              " and n.nspname in ('prestogres_catalog')" \
         | 
| 249 | 
            -
                              " and n.nspname !~ '^pg_toast'"
         | 
| 250 | 
            -
                        for row in plpy.cursor(sql):
         | 
| 251 | 
            -
                            plpy.execute("drop table %s.%s" % (plpy.quote_ident(row["schema_name"]), plpy.quote_ident(row["table_name"])))
         | 
| 252 | 
            -
             | 
| 253 | 
            -
                        # create schemas
         | 
| 254 | 
            -
                        for schema_name in schema_names:
         | 
| 255 | 
            -
                            try:
         | 
| 256 | 
            -
                                plpy.execute("create schema %s" % plpy.quote_ident(schema_name))
         | 
| 257 | 
            -
                            except:
         | 
| 258 | 
            -
                                # ignore error
         | 
| 259 | 
            -
                                pass
         | 
| 260 | 
            -
             | 
| 261 | 
            -
                        # create tables
         | 
| 262 | 
            -
                        for statement in statements:
         | 
| 263 | 
            -
                            plpy.execute(statement)
         | 
| 264 | 
            -
             | 
| 265 | 
            -
                        # run the actual query
         | 
| 266 | 
            -
                        metadata = plpy.execute(query)
         | 
| 267 | 
            -
                        result = map(lambda row: row.values(), metadata)
         | 
| 258 | 
            +
                    query_result = query_cache.get(query)
         | 
| 268 259 |  | 
| 269 | 
            -
                     | 
| 270 | 
            -
                         | 
| 271 | 
            -
                         | 
| 260 | 
            +
                    if query_result:
         | 
| 261 | 
            +
                        column_names = query_result.column_names
         | 
| 262 | 
            +
                        column_types = query_result.column_types
         | 
| 263 | 
            +
                        result = query_result.result
         | 
| 272 264 |  | 
| 273 | 
            -
                     | 
| 274 | 
            -
             | 
| 275 | 
            -
             | 
| 276 | 
            -
             | 
| 265 | 
            +
                    else:
         | 
| 266 | 
            +
                        # enter subtransaction to rollback tables right after running the query
         | 
| 267 | 
            +
                        subxact = plpy.subtransaction()
         | 
| 268 | 
            +
                        subxact.enter()
         | 
| 269 | 
            +
                        try:
         | 
| 270 | 
            +
                            # delete all schemas excepting prestogres_catalog
         | 
| 271 | 
            +
                            sql = "select n.nspname as schema_name from pg_catalog.pg_namespace n" \
         | 
| 272 | 
            +
                                  " where n.nspname not in ('prestogres_catalog', 'pg_catalog', 'information_schema', 'public')" \
         | 
| 273 | 
            +
                                  " and n.nspname !~ '^pg_toast'"
         | 
| 274 | 
            +
                            for row in plpy.cursor(sql):
         | 
| 275 | 
            +
                                plpy.execute("drop schema %s cascade" % plpy.quote_ident(row["schema_name"]))
         | 
| 276 | 
            +
             | 
| 277 | 
            +
                            # delete all tables in prestogres_catalog
         | 
| 278 | 
            +
                            # relkind = 'r' takes only tables and skip views, indexes, etc.
         | 
| 279 | 
            +
                            sql = "select n.nspname as schema_name, c.relname as table_name from pg_catalog.pg_class c" \
         | 
| 280 | 
            +
                                  " left join pg_catalog.pg_namespace n on n.oid = c.relnamespace" \
         | 
| 281 | 
            +
                                  " where c.relkind in ('r')" \
         | 
| 282 | 
            +
                                  " and n.nspname in ('prestogres_catalog')" \
         | 
| 283 | 
            +
                                  " and n.nspname !~ '^pg_toast'"
         | 
| 284 | 
            +
                            for row in plpy.cursor(sql):
         | 
| 285 | 
            +
                                plpy.execute("drop table %s.%s" % (plpy.quote_ident(row["schema_name"]), plpy.quote_ident(row["table_name"])))
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                            # create schemas
         | 
| 288 | 
            +
                            for schema_name in schema_names:
         | 
| 289 | 
            +
                                try:
         | 
| 290 | 
            +
                                    plpy.execute("create schema %s" % plpy.quote_ident(schema_name))
         | 
| 291 | 
            +
                                except:
         | 
| 292 | 
            +
                                    # ignore error
         | 
| 293 | 
            +
                                    pass
         | 
| 294 | 
            +
             | 
| 295 | 
            +
                            # create tables
         | 
| 296 | 
            +
                            for statement in statements:
         | 
| 297 | 
            +
                                plpy.execute(statement)
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                            # run the actual query
         | 
| 300 | 
            +
                            metadata = plpy.execute(query)
         | 
| 301 | 
            +
                            column_names = metadata.colnames()
         | 
| 302 | 
            +
                            column_type_oids = metadata.coltypes()
         | 
| 303 | 
            +
                            result = map(lambda row: map(row.get, column_names), metadata)
         | 
| 304 | 
            +
             | 
| 305 | 
            +
                            # table schema
         | 
| 306 | 
            +
                            oid_to_type_name = _load_oid_to_type_name_mapping(column_type_oids)
         | 
| 307 | 
            +
                            column_types = map(oid_to_type_name.get, column_type_oids)
         | 
| 308 | 
            +
             | 
| 309 | 
            +
                            query_cache[query] = QueryResult(column_names, column_types, result)
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                        finally:
         | 
| 312 | 
            +
                            # rollback subtransaction
         | 
| 313 | 
            +
                            subxact.exit("rollback subtransaction", None, None)
         | 
| 277 314 |  | 
| 278 315 | 
             
                    create_sql = _build_create_temp_table_sql(result_table, column_names, column_types)
         | 
| 279 316 | 
             
                    insert_sql, values_sql_format = _build_insert_into_sql(result_table, column_names)
         | 
    
        data/pgsql/setup.sql
    CHANGED
    
    | @@ -19,10 +19,11 @@ create or replace function prestogres_catalog.run_system_catalog_as_temp_table( | |
| 19 19 | 
             
                "server" text,
         | 
| 20 20 | 
             
                "user" text,
         | 
| 21 21 | 
             
                "catalog" text,
         | 
| 22 | 
            +
                "schema" text,
         | 
| 22 23 | 
             
                "table_name" text,
         | 
| 23 24 | 
             
                "query" text)
         | 
| 24 25 | 
             
            returns void as $$
         | 
| 25 26 | 
             
            import prestogres
         | 
| 26 | 
            -
            prestogres.run_system_catalog_as_temp_table(server, user, catalog, table_name, query)
         | 
| 27 | 
            +
            prestogres.run_system_catalog_as_temp_table(server, user, catalog, schema, table_name, query)
         | 
| 27 28 | 
             
            $$ language plpythonu;
         | 
| 28 29 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,55 +1,62 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: prestogres
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.3.0
         | 
| 5 | 
            +
              prerelease: 
         | 
| 5 6 | 
             
            platform: ruby
         | 
| 6 7 | 
             
            authors:
         | 
| 7 8 | 
             
            - Sadayuki Furuhashi
         | 
| 8 9 | 
             
            autorequire: 
         | 
| 9 10 | 
             
            bindir: bin
         | 
| 10 11 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2014- | 
| 12 | 
            +
            date: 2014-02-07 00:00:00.000000000 Z
         | 
| 12 13 | 
             
            dependencies:
         | 
| 13 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 15 | 
             
              name: bundler
         | 
| 15 16 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 17 | 
            +
                none: false
         | 
| 16 18 | 
             
                requirements:
         | 
| 17 | 
            -
                - -  | 
| 19 | 
            +
                - - ~>
         | 
| 18 20 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 21 | 
             
                    version: '1.0'
         | 
| 20 22 | 
             
              type: :development
         | 
| 21 23 | 
             
              prerelease: false
         | 
| 22 24 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 25 | 
            +
                none: false
         | 
| 23 26 | 
             
                requirements:
         | 
| 24 | 
            -
                - -  | 
| 27 | 
            +
                - - ~>
         | 
| 25 28 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 29 | 
             
                    version: '1.0'
         | 
| 27 30 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 28 31 | 
             
              name: rake
         | 
| 29 32 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 33 | 
            +
                none: false
         | 
| 30 34 | 
             
                requirements:
         | 
| 31 | 
            -
                - -  | 
| 35 | 
            +
                - - ~>
         | 
| 32 36 | 
             
                  - !ruby/object:Gem::Version
         | 
| 33 37 | 
             
                    version: 0.9.2
         | 
| 34 38 | 
             
              type: :development
         | 
| 35 39 | 
             
              prerelease: false
         | 
| 36 40 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 41 | 
            +
                none: false
         | 
| 37 42 | 
             
                requirements:
         | 
| 38 | 
            -
                - -  | 
| 43 | 
            +
                - - ~>
         | 
| 39 44 | 
             
                  - !ruby/object:Gem::Version
         | 
| 40 45 | 
             
                    version: 0.9.2
         | 
| 41 46 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 42 47 | 
             
              name: rake-compiler
         | 
| 43 48 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 49 | 
            +
                none: false
         | 
| 44 50 | 
             
                requirements:
         | 
| 45 | 
            -
                - -  | 
| 51 | 
            +
                - - ~>
         | 
| 46 52 | 
             
                  - !ruby/object:Gem::Version
         | 
| 47 53 | 
             
                    version: 0.8.3
         | 
| 48 54 | 
             
              type: :development
         | 
| 49 55 | 
             
              prerelease: false
         | 
| 50 56 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 57 | 
            +
                none: false
         | 
| 51 58 | 
             
                requirements:
         | 
| 52 | 
            -
                - -  | 
| 59 | 
            +
                - - ~>
         | 
| 53 60 | 
             
                  - !ruby/object:Gem::Version
         | 
| 54 61 | 
             
                    version: 0.8.3
         | 
| 55 62 | 
             
            description: Presto PostgreSQL protocol gateway
         | 
| @@ -61,10 +68,9 @@ extensions: | |
| 61 68 | 
             
            - ext/extconf.rb
         | 
| 62 69 | 
             
            extra_rdoc_files: []
         | 
| 63 70 | 
             
            files:
         | 
| 64 | 
            -
            -  | 
| 71 | 
            +
            - .gitignore
         | 
| 65 72 | 
             
            - ChangeLog
         | 
| 66 73 | 
             
            - Gemfile
         | 
| 67 | 
            -
            - Gemfile.lock
         | 
| 68 74 | 
             
            - LICENSE
         | 
| 69 75 | 
             
            - NOTICE
         | 
| 70 76 | 
             
            - README.md
         | 
| @@ -463,25 +469,32 @@ files: | |
| 463 469 | 
             
            homepage: https://github.com/treasure-data/prestogres
         | 
| 464 470 | 
             
            licenses:
         | 
| 465 471 | 
             
            - Apache 2.0
         | 
| 466 | 
            -
            metadata: {}
         | 
| 467 472 | 
             
            post_install_message: 
         | 
| 468 473 | 
             
            rdoc_options: []
         | 
| 469 474 | 
             
            require_paths:
         | 
| 470 475 | 
             
            - lib
         | 
| 471 476 | 
             
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 477 | 
            +
              none: false
         | 
| 472 478 | 
             
              requirements:
         | 
| 473 | 
            -
              - -  | 
| 479 | 
            +
              - - ! '>='
         | 
| 474 480 | 
             
                - !ruby/object:Gem::Version
         | 
| 475 481 | 
             
                  version: '0'
         | 
| 482 | 
            +
                  segments:
         | 
| 483 | 
            +
                  - 0
         | 
| 484 | 
            +
                  hash: -1048444669451031740
         | 
| 476 485 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 486 | 
            +
              none: false
         | 
| 477 487 | 
             
              requirements:
         | 
| 478 | 
            -
              - -  | 
| 488 | 
            +
              - - ! '>='
         | 
| 479 489 | 
             
                - !ruby/object:Gem::Version
         | 
| 480 490 | 
             
                  version: '0'
         | 
| 491 | 
            +
                  segments:
         | 
| 492 | 
            +
                  - 0
         | 
| 493 | 
            +
                  hash: -1048444669451031740
         | 
| 481 494 | 
             
            requirements: []
         | 
| 482 495 | 
             
            rubyforge_project: 
         | 
| 483 | 
            -
            rubygems_version:  | 
| 496 | 
            +
            rubygems_version: 1.8.23
         | 
| 484 497 | 
             
            signing_key: 
         | 
| 485 | 
            -
            specification_version:  | 
| 498 | 
            +
            specification_version: 3
         | 
| 486 499 | 
             
            summary: Presto PostgreSQL protocol gateway
         | 
| 487 500 | 
             
            test_files: []
         | 
    
        checksums.yaml
    DELETED
    
    | @@ -1,7 +0,0 @@ | |
| 1 | 
            -
            ---
         | 
| 2 | 
            -
            SHA1:
         | 
| 3 | 
            -
              metadata.gz: fdbbafba90e2dde6d7340746b30d369eda073ed9
         | 
| 4 | 
            -
              data.tar.gz: 57d91cbb2bb74c2ce53132ea9309eb9a0cb47e09
         | 
| 5 | 
            -
            SHA512:
         | 
| 6 | 
            -
              metadata.gz: f166e0435a473ec6930522f0a139733f24227a8b0045725fc1e89f4afda25c6fd589c2dc121a46e99c82f79bba135c601b42fec45651c66c185a0aaae6f52eb6
         | 
| 7 | 
            -
              data.tar.gz: c351d1a8fe7c59cc7b9a2ec603935766141958df839d4f7179a9921e9410b2da513f6b05beab2f6b5d3d96be309542df876b01fce42f4021f0692d40ceb84652
         | 
    
        data/Gemfile.lock
    DELETED
    
    | @@ -1,20 +0,0 @@ | |
| 1 | 
            -
            PATH
         | 
| 2 | 
            -
              remote: .
         | 
| 3 | 
            -
              specs:
         | 
| 4 | 
            -
                prestogres (0.1.0)
         | 
| 5 | 
            -
             | 
| 6 | 
            -
            GEM
         | 
| 7 | 
            -
              remote: https://rubygems.org/
         | 
| 8 | 
            -
              specs:
         | 
| 9 | 
            -
                rake (0.9.6)
         | 
| 10 | 
            -
                rake-compiler (0.8.3)
         | 
| 11 | 
            -
                  rake
         | 
| 12 | 
            -
             | 
| 13 | 
            -
            PLATFORMS
         | 
| 14 | 
            -
              ruby
         | 
| 15 | 
            -
             | 
| 16 | 
            -
            DEPENDENCIES
         | 
| 17 | 
            -
              bundler (~> 1.0)
         | 
| 18 | 
            -
              prestogres!
         | 
| 19 | 
            -
              rake (~> 0.9.2)
         | 
| 20 | 
            -
              rake-compiler (~> 0.8.3)
         |