How can I enable autocompletion in psql in more cases? - postgresql

I'm a newbie for RDBMS.
Postgres helps me with auto-completion but it doesn't work for FROM, WHERE, and DISTINCT in the SELECT clause.
Of course, it is already connected to the database. There are also the schema and table to query.
For example, all keywords following the SELECT will not be auto-completed, when I try to enter the following query;
SELECT DISTINCT district FROM city WHERE countrycode = 'JPN';
However, there is no error after I finished typing manually and running. Postgres returns the result normally.
Nonetheless, it works in other clauses such as CREATE and ALTER.
How can I auto-complete these?
Thank you.

Keywords between SELECT and FROM ("distinct" and "district" in your example) cannot be auto-completed because the parser does not know what columns, keywords, function names, etc. you are referring to. If you type SELECT DI and press Tab, the parser will not know whether you are trying to complete the DISTINCT keyword or the DISTRICT column name (bear in mind that in Postgres, words are interpreted in case-insensitive fashion, unless double-quotes " are used). After the FROM keyword, the parser knows that you are likely going to type in a table name, so it is able to support tab-completion.
Disclosure: I am an EnterpriseDB (EDB) employee

richyen's answer is correct as far as column names are concerned.
However, PostgreSQL could certainly offer auto-completion for DISTINCT. DISTINCT is a reserved keyword in SQL and cannot be used as a column names unless you quote it with double quotes.
The reason why there is no auto-completion for DISTINCT is that nobody has implemented it yet.

Related

postgres db query . How to use single quote and double quote and how to get the join working

I am using postgresdb and I ran into an issue running queries using pdAdmin...
Here are the tables that I have :
user table
There is a transaction table like this.
Here are the queries that I am looking for.
How to join the two table to get the join result on 'user.id' and 'transaction.partnerUserId' table.. when I am running it , I am not getting any result and there is the single quote and double quote confustion too..
anybody can help with the query...
Run the query as:
select "firstName", amount from "user" join transaction on "user".id = transaction."partnerUserId ;
Identifiers need to be double quoted if they are a reserved word or some form of "MixedCase" or "UPPERCASE", per documentation here Identifiers. NOTE, this is for Postgres which works opposite the SQL standard in lower casing unquoted identifiers instead of upper casing them. I personally use lower case identifiers with underscores where necessary.

Query insists on quoted columns

I have a local copy of Postgres running, and I'm working on a C# .Net Core 2.1 app using nHibernate as an ORM.
It's started throwing an exception: PostgresException: 42703: column this_.datasetname does not exist
When I copy the SQL and run in pgAdmin I get a similar error.
This is a short version of the SQL which gives the same error:
SELECT this_.datasetName FROM orders this_
ERROR: column this_.datasetname does not exist LINE 1: SELECT
this_.datasetName FROM orders this_
^ HINT: Perhaps you meant to reference the column "this_.datasetName". SQL state: 42703 Character: 8
If I add quotes around the column name (but not around _this. as suggested) it works, but obviously I can't tell nHibernate to do that.
SELECT this_."datasetName" FROM orders this_
The following also works fine:
SELECT "datasetName" FROM orders
Why would it insist on adding the quotes? It never used to.
That's because this column was created with the surrounding double quotes in the first place - this makes the identifier case-sensitive, while by default it isn't. Since the identifier contains mixed case, you are stucked: the identifier needs to be quoted everywhere you use it.
If you look at the definition of the table, you will see something like:
create table orders (
...,
"datasetName" text,
...
)
I would strongly suggest fixing your schema. Quoted identifiers add no value in general, while on the other hand they make things unnecessary complicated. Camel case does not fill well for database identifiers, snake case is better, since case is not meaningful:
create table orders (
...,
dataset_name text,
...
)

Postgres multi table join when tables are capitalized

The software I used created tables in postgres with Capitalizations, and I know that postgres and caps are a pain to deal with. I am using a multi-table query but they have Caps and I am not sure how to get the query down correctly to make it work.
I have two databases TBLS and DBS. I want to get the column TBL_NAME where the two DB_ID's are the same.
Here is what I thought might work:
select '"t.TBL_NAME"' from "TBLS" t, "DBS" d where '"t.DB_ID"'='"d.DB_ID"';
Any way I try and place the " or ' I can't seem to get the query to work correctly.
"tablename"."columnname"
See the manual on SQL syntax.
'"X.COL"' is a string literal with content string "X.COL".
"X.COL" is a single unqualified identifier for the object named X.COL. Yes, table, column, etc names can have a . in them.
"X"."COL" is a qualified identifier for COL in object X. Depending on context it can mean "the table COL in schema X", "the column COL in table X", etc. This is the one you want.

Is it possible to get explain plan with bind variables in DB2?

With Oracle, the syntax is:
explain plan for
select * from users WHERE user_name = :user_name AND user_dob = :user_dob
Is it possible to do the same in DB2? The statement below does not seem to work.
explain plan with snapshot for
select * from users WHERE user_name = :user_name AND user_dob = :user_dob
Thank you.
The answer may depend on your DB2 version and platform, which you chose not to share with us for some reason. This works fine on DB2 for LUW (v10.1, but I'm sure it would work with v9.7 and up):
$ db2 "explain plan with snapshot for select * from syscat.schemata where schemaname = :blah"
DB20000I The SQL command completed successfully.
You may want to try replacing named parameter markers with questions marks.
Apparently, the answer is in the IBM website, but it is not easy to make sense of.
http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=%2Fcom.ibm.db2.udb.admin.doc%2Fdoc%2Fr0000952.htm
FOR explainable-sql-statement
Specifies the SQL statement to be explained. This statement can be any
valid CALL, Compound SQL (Dynamic), DELETE, INSERT, MERGE, SELECT,
SELECT INTO, UPDATE, VALUES, or VALUES INTO SQL statement. If the
EXPLAIN statement is embedded in a program, the
explainable-sql-statement can contain references to host variables
(these variables must be defined in the program). Similarly, if
EXPLAIN is being dynamically prepared, the explainable-sql-statement
can contain parameter markers.
But it does not tell you what "parameter markers" are, so you have to go and search for it.

Is name a special keyword in PostgreSQL?

I am using Ubuntu and PostgreSql 8.4.9.
Now, for any table in my database, if I do select table_name.name from table_name, it shows a result of concatenated columns for each row, although I don't have any name column in the table. For the tables which have name column, no issue. Any idea why?
My results are like this:
select taggings.name from taggings limit 3;
---------------------------------------------------------------
(1,4,84,,,PlantCategory,soil_pref_tags,"2010-03-18 00:37:55")
(2,5,84,,,PlantCategory,soil_pref_tags,"2010-03-18 00:37:55")
(3,6,84,,,PlantCategory,soil_pref_tags,"2010-03-18 00:37:55")
(3 rows)
select name from taggings limit 3;
ERROR: column "name" does not exist
LINE 1: select name from taggings limit 3;
This is a known confusing "feature" with a bit of history. Specifically, you could refer to tuples from the table as a whole with the table name, and then appending .name would invoke the name function on them (i.e. it would be interpreted as select name(t) from t).
At some point in the PostgreSQL 9 development, Istr this was cleaned up a bit. You can still do select t from t explicitly to get the rows-as-tuples effect, but you can't apply a function in the same way. So on PostgreSQL 8.4.9, this:
create table t(id serial primary key, value text not null);
insert into t(value) values('foo');
select t.name from t;
produces the bizarre:
name
---------
(1,foo)
(1 row)
but on 9.1.1 produces:
ERROR: column t.name does not exist
LINE 1: select t.name from t;
^
as you would expect.
So, to specifically answer your question: name is a standard type in PostgreSQL (used in the catalogue for table names etc) and also some standard functions to convert things to the name type. It's not actually reserved, just the objects that exist called that, plus some historical strange syntax, made things confusing; and this has been fixed by the developers in recent versions.
According to the PostgreSQL documentation, name is a "non-reserved" keyword in PostgreSQL, SQL:2003, SQL:1999, or SQL-92.
SQL distinguishes between reserved and non-reserved key words. According to the standard, reserved key words are the only real key words; they are never allowed as identifiers. Non-reserved key words only have a special meaning in particular contexts and can be used as identifiers in other contexts. Most non-reserved key words are actually the names of built-in tables and functions specified by SQL. The concept of non-reserved key words essentially only exists to declare that some predefined meaning is attached to a word in some contexts.
The suggested fix when using keywords is:
As a general rule, if you get spurious parser errors for commands that contain any of the listed key words as an identifier you should try to quote the identifier to see if the problem goes away.