Does sqflite support query with 'CASE WHEN'? - case-when

I try to run a query via sqflite and get the error below:
DatabaseException(no such column: true (code 1): , while compiling: select (case true WHEN true THEN 111 END) xkey1 from tb_path
Here are the SQL steps:
create table tb_path(name text, age text);
db.rawQuery('select (case true WHEN true THEN 111 END) xkey1 from tb_path');
and the error above showed up.
If I try to run the SQL via SqlLite Expert Personal (a windows version SQLITE tool), this works fine.

When I try your steps in sqlite command line (Ubuntu 18.04):
$ select sqlite_version();
3.22.0
$ CREATE TABLE tb_path(from_ text, to_ text);
$ select (case true WHEN true THEN 111 END) xkey1 from tb_path;
Error: no such column: true
If I try with the latest binary download (3.27), I don't get the error:
$ select sqlite_version();
3.27.2
$ CREATE TABLE tb_path(from_ text, to_ text);
$ select (case true WHEN true THEN 111 END) xkey1 from tb_path;
So maybe such statement is only valid for newer sqlite version and since sqflite uses whatever the iOS/Android platform provides, it might not be supported yet (see a good list of shipping sqlite version on Android here: Version of SQLite used in Android?)

Related

Rails 4.2 Postgres 9.4.4 statement_timeout doesn't work

I am trying to set a statement_timeout. I tried both setting in database.yml file like this
variables:
statement_timeout: 1000
And this
ActiveRecord::Base.connection.execute("SET statement_timeout = 1000")
Tested with
ActiveRecord::Base.connection.execute("select pg_sleep(4)")
And they both don't have any effect.
I am running postgres 10 in my local and the statement_timeouts works just expected. But on my server that is running postgres 9.4.4, it simply doesn't do anything.
I've check Postgres' doc for 9.4 and statement_timeout is available. Anyone can shed some light?
I wasn't able to replicate this issue locally using: Postgresql 9.4.26. But it might be useful to share what I've tried and some thoughts around the server issue.
Here is what I've tried (a useful bit might be a query to verify the PG version from rails):
# Confirming I am executing against 9.4.x PG:
irb(main):002:0> ActiveRecord::Base.connection.execute("select version()")
(10.8ms) select version()
=> #<PG::Result:0x00007ff74782e060 status=PGRES_TUPLES_OK ntuples=1 nfields=1 cmd_tuples=1>
irb(main):003:0> _.first
=> {"version"=>"PostgreSQL 9.4.26 on x86_64-apple-darwin18.7.0, compiled by Apple clang version 11.0.0 (clang-1100.0.33.17), 64-bit"}
# Set timeout:
irb(main):004:0> ActiveRecord::Base.connection.execute("SET statement_timeout = 1000")
(0.4ms) SET statement_timeout = 1000
=> #<PG::Result:0x00007ff7720a3d88 status=PGRES_COMMAND_OK ntuples=0 nfields=0 cmd_tuples=0>
# Confirm it works - it is ~1s and also stacktrace is pretty explicit about it:
irb(main):005:0> ActiveRecord::Base.connection.execute("select pg_sleep(4)")
(1071.2ms) select pg_sleep(4)
.... (stacktrace hidden)
ActiveRecord::StatementInvalid (PG::QueryCanceled: ERROR: canceling statement due to statement timeout)
: select pg_sleep(4)
Here is what to try
Since the issue occurs on server only and since statement_timeout works on other minor version and locally, one thing that comes to mind is the lack of privileges to update statement_timeout from where it is attempted. Perhaps rails pg login used to make db connection is not allowed to update that setting.
The best would be to verify that either via rails console on a server:
irb(main):004:0> ActiveRecord::Base.connection.execute("SET statement_timeout = 1000")
irb(main):004:0> irb(main):003:0> ActiveRecord::Base.connection.execute("show statement_timeout").first
(0.2ms) show statement_timeout
=> {"statement_timeout"=>"1s"}
Or, it can be checked directly via psql console (some deployments allow this too):
psql myserveruser # if this was heroku's pg: heroku pg:psql
postgres=# set statement_timeout = 1000;
SET
postgres=# select pg_sleep(4);
ERROR: canceling statement due to statement timeout
Time: 1068.067 ms (00:01.068)
Other thing to keep in mind (taken from https://dba.stackexchange.com/a/83035/90903):
The way statement_timeout works, the time starts counting when the
server receives a new command from the client...
And if a function does SET statement_timeout = 100; it will have an effect only starting at
the next command from the client.

Rails test DB constantly losing my PostgreSQL functions

My project uses a few custom PostgreSQL stored functions for some features that would be a pain in raw SQL or ActiveRecord. Every now and then I will run the RSpec test suite, and find that all my stored functions have been blown away. Re-running the migrations to create them fixes the problem, but "rake db:structure:load" does NOT.
I am deeply confused. I never drop either the dev or test database unless this happens, but my functions are like Schrodinger's PL/pgSQL. I am REALLY hoping this never happens in production.
Here is an example of a failing test and my attempts to fix it:
ActiveRecord::StatementInvalid:
PG::UndefinedFunction: ERROR: function round_half_down(numeric) does not exist
# Damn. We have to drop the database so we can reload structure.sql:
$ RAILS_ENV=test rake db:drop
$ RAILS_ENV=test rake db:create
# load structure.sql instead of schema.rb:
$ RAILS_ENV=test rake db:structure:load
# Not fixed:
ActiveRecord::StatementInvalid:
PG::UndefinedFunction: ERROR: function round_half_down(numeric) does not exist
$ RAILS_ENV=test rake db:migrate:redo VERSION=20160421184708
== 20171002190107 CreateRoundHalfDownFunction: reverting ======================
-- execute("DROP FUNCTION IF EXISTS round_half_down(numeric)")
-> 0.0004s
== 20171002190107 CreateRoundHalfDownFunction: reverted (0.0005s) =============
== 20171002190107 CreateRoundHalfDownFunction: migrating ======================
-- execute("CREATE OR REPLACE FUNCTION ROUND_HALF_DOWN(NUMERIC)\n RETURNS NUMERIC LANGUAGE SQL AS\n$FUNC$\n SELECT CASE WHEN ($1%1) < 0.6 THEN FLOOR($1) ELSE CEIL($1) END;\n$FUNC$\n")
-> 0.0014s
== 20171002190107 CreateRoundHalfDownFunction: migrated (0.0014s) =============
Now it is fixed!
Yes, I verified that the function is present in structure.sql:
--
-- Name: round_half_down(numeric); Type: FUNCTION; Schema: public; Owner: -
--
CREATE FUNCTION round_half_down(numeric) RETURNS numeric
LANGUAGE sql
AS $_$
SELECT CASE WHEN ($1%1) < 0.6 THEN FLOOR($1) ELSE CEIL($1) END;
$_$;
For the record, this stopped happening to me with newer versions of the pg gem and PostgreSQL itself. I also added config.active_record.schema_format = :sql to application.rb, because my application makes heavy use of Postgres-specific features, and a number of stored functions.

pgAdmin Editor Rails execute SQL from file

Rails Code:
sql = File.read("#{Rails.root}/scripts/refresh.sql")
db_con = ActiveRecord::Base.connection
db_con.execute(sql)
file refresh.sql:
select 1;
If I create or modify file refresh.sql in pgAdmin (Ubuntu or Windows) I will get the following error:
PG::SyntaxError: ERROR: syntax error at or near "select"
LINE 1: select 1;
However, if I copy and paste the sql text into a text editor (sublime or gedit) and overwrite file refresh.sql the code runs
pgAdmin III main window
File => Options => Query file
Uncheck option "Read and write Unicode UTF-8 files"

Texticle fuzzy search not finding anything in Ruby on Rails

I've added the following to my gemfile:
gem 'texticle', "2.0", :require => 'texticle/rails' # search gem
I then ran bundle install and bundle installed the gem
I'm using Rails 3.1.0 and I have am using a Postgres database.
I verify that I actually have the string I am looking for in the database table:
ruby-1.9.2-p290 :004 > Hotel.first
Hotel Load (0.4ms) SELECT "hotels".* FROM "hotels" LIMIT 1
=> #<Hotel id: 1, title: "Marriot Hotel", created_at: "2012-03-01 23:53:16", updated_at: "2012-03-01 23:53:16">
When I run `Hotel.search('e')
ruby-1.9.2-p290 :005 > Hotel.search(:title => 'e')
Hotel Load (1.4ms) SELECT "hotels".*, ts_rank(to_tsvector("hotels"."title"), to_tsquery('e')) AS "rank0.4785527956789428" FROM "hotels" WHERE (to_tsvector('english', "title") ## to_tsquery('e')) ORDER BY "rank0.4785527956789428" DESC
=> []
I get nothing. I tried running Hotel.search('e') and still nothing. If I try Hotel.search(:title => 'Marriot') then it works but the reason I am using Texticle is for the fuzzy search.
Am I missing any other configurations?
Thanks
There are a couple things I would suggest checking:
Verify an extension has been created manually for each database involved. I didn't have luck with 'texticle:install_trigram'. And if you're using Heroku, there may be additional steps, especially if you haven't migrated from your shared database.
Use the fuzzy_search method. In the latest version of Texticle, there are actually 3 new methods; the original #search method has been deprecated.
To manually install the extension:
Local Dev/Test
psql -U <username>
\l
\c db_development
CREATE EXTENSION pg_trgm;
\dx
\c db_test
CREATE EXTENSION pg_trgm;
\dx
\q
Heroku Integration/Production
heroku pg:psql
\dx
CREATE EXTENSION pg_trgm;
\dx
More?
PostgreSQL Trigrams (fuzzy search)
What's new in PostgreSQL 9.1 - PostgreSQL wiki
trigram | Tumblr
Installing PostgreSQL Trigram
Install Trigram Rake Task by benhamill · Pull Request #63 · tenderlove/texticle · GitHub
texticle:install_trigram - on Heroku? · Issue #15 · tenderlove/texticle · GitHub
New Texticle search methods (source code)
texticle/lib/texticle.rb at master · texticle/texticle · GitHub
My understanding of the way Texticle works is that it's going to do full text search on your string columns but not necessarily do fuzzy search by default. If you look at the query that it's generating in Postgres, it's looking for a match on 'e' rather than any word that contains the letter 'e'.
You can read the Postgres docs here:
http://www.postgresql.org/docs/9.1/static/datatype-textsearch.html
That said, I see support for prefix matching but not postfix in the docs, although I might be missing something.
What happens if you do Hotel.search('Marr:*') ?

facing a postgres error while running rake migration

I am getting the following uuid error while running a rails app with postgres as backend. Can someone help me out with which dependency is needed.
[root#localhost webapp]# rake db:migrate
(in /root/mysite/webapp)
== CreateContributors: migrating =============================================
-- create_table(:contributors, {:id=>false})
-> 0.0121s
-- execute("alter table contributors add primary key (id)")
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "contributors_pkey" for table "contributors"
-> 0.0797s
-- execute("alter table contributors alter column id set default uuid_generate_v1()::varchar")
rake aborted!
An error has occurred, this and all later migrations canceled:
PGError: ERROR: function uuid_generate_v1() does not exist
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
: alter table contributors alter column id set default uuid_generate_v1()::varchar
The uuid_generate_v1() function is part of the uuid-ossp package and you have to install that into PostgreSQL before you can use it. You should have a file called uuid-ossp.sql in your PostgreSQL contrib directory. You can install the package with:
$ psql -d your_database < /the/path/to/uuid-ossp.sql
You'll probably want to run that as the database super user.

Resources