Phoenix sqlline can not query system table SYSTEM.FUNCTION - apache-phoenix

I know Apache Phoenix will store all function metadata in SYSTEM.FUNCTION, but when I perform the query use following statement it will throw exception.
0: jdbc:phoenix:10.1.226.15:2181> select * from SYSTEM.FUNCTION;
Error: ERROR 604 (42P00): Syntax error. Mismatched input. Expecting "NAME", got "FUNCTION" at line 1, column 22. (state=42P00,code=604)
org.apache.phoenix.exception.PhoenixParserException: ERROR 604 (42P00): Syntax error. Mismatched input. Expecting "NAME", got "FUNCTION" at line 1, column 22.
at org.apache.phoenix.exception.PhoenixParserException.newException(PhoenixParserException.java:33)
or
0: jdbc:phoenix:10.1.226.15:2181> select * from FUNCTION;
Error: ERROR 601 (42P00): Syntax error. Encountered "FUNCTION" at line 1, column 15. (state=42P00,code=601)
org.apache.phoenix.exception.PhoenixParserException: ERROR 601 (42P00): Syntax error. Encountered "FUNCTION" at line 1, column 15.
The table FUNCTION exist in SYSTEM schema, but can not query, in other hand, the table CATALOG in SYSTEM schema I can perform statement and retrieves the right data.
0: jdbc:phoenix:10.1.226.15:2181> !tables
+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | TABLE_TYPE | REMARKS |
+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------+
| | SYSTEM | CATALOG | SYSTEM TABLE | |
| | SYSTEM | FUNCTION | SYSTEM TABLE | |
| | SYSTEM | SEQUENCE | SYSTEM TABLE | |
| | SYSTEM | STATS | SYSTEM TABLE | |
+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------+
0: jdbc:phoenix:10.1.226.15:2181> select * from system.catalog;
+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------+
| TENANT_ID | TABLE_SCHEM | TABLE_NAME | COLUMN_NAME | COLUMN_FAMILY |
+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------------+------------------------------------+
| | SYSTEM | CATALOG | | |
| | SYSTEM | CATALOG | ARRAY_SIZE | 0 |
| | SYSTEM | CATALOG | BUFFER_LENGTH | 0 |
....
Can somebody explain why?

function, like select, is a reserved keyword. If you would like to refer to the table, enclose it in quotations (and it will also become case-sensitive).

Related

PostgreSQL, import a csv file

I'm trying to copy a CSV file into an empty table, after trying to match the columns in the CSV which failed with the exact same error.
COPY books
FROM '/path/to/file/books.csv' CSV HEADER;
error:
ERROR: extra data after last expected column
CONTEXT: COPY books, line 2: "1,Harry Potter and the Half-Blood Prince (Harry Potter #6),J.K. Rowling/Mary GrandPré,4.57,0439785..."
SQL state: 22P04
Also, I would like that the publication_date will be of date type, so it can be queried, How can that be applied during copying?
a piece of the CSV file:
bookID| title | authors | average_rating | isbn|isbn13 |num_pages | ratings_count| text_reviews_count| publication_date|
----------------------------------------------------------------------------------------------------------------------------------
1 | harry potter | | | |
|(harry Potter | | | |
| #6) | author | 4 |"num" | "num"| 600 | 3243 | 534 | 01/01/2000 |
SELECT * FROM books
output:
bookID| title | authors | average_rating | isbn |isbn13| language_code
---------------------------------------------------------------------------------
text | character| text | integer | text | text | character |
| varying | | | | | varying
| num_pages | ratings_count| text_reviews_count| publication_date| publisher
-------------------------------------------------------------------------------
| integer | bigint | bigint | date | character
varying
First of all, the columns number mismatch from CSV file and TABLE, but you can specify via COPY command the columns for the table that you need:
COPY books (bookID,title,authors,average_rating,isbn,isbn13,num_pages,ratings_count , text_reviews_count , publication_date) FROM '/path/to/file/books.csv' CSV header delimiter ',';
You can specify you delimiter

SQL parameter table

I suspect this question is already well-answered but perhaps due to limited SQL vocabulary I have not managed to find what I need. I have a database with many code:description mappings in a single 'parameter' table. I would like to define a query or procedure to return the descriptions for all (or an arbitrary list of) coded values in a given 'content' table with their descriptions from the parameter table. I don't want to alter the original data, I just want to display friendly results.
Is there a standard way to do this?
Can it be accomplished with SELECT or are other statements required?
Here is a sample query for a single coded field:
SELECT TOP (5)
newid() as id,
B.BRIDGE_STATUS,
P.SHORTDESC
FROM
BRIDGE B
LEFT JOIN PARAMTRS P ON P.TABLE_NAME = 'BRIDGE'
AND P.FIELD_NAME = 'BRIDGE_STATUS'
AND P.PARMVALUE = B.BRIDGE_STATUS
ORDER BY
id
I want to produce 'decoded' results like:
| id | BRIDGE_STATUS |
|--------------------------------------|------------ |
| BABCEC1E-5FE2-46FA-9763-000131F2F688 | Active |
| 758F5201-4742-43C6-8550-000571875265 | Active |
| 5E51634C-4DD9-4B0A-BBF5-00087DF71C8B | Active |
| 0A4EA521-DE70-4D04-93B8-000CD12B7F55 | Inactive |
| 815C6C66-8995-4893-9A1B-000F00F839A4 | Proposed |
Rather than original, coded data like:
| id | BRIDGE_STATUS |
|--------------------------------------|---------------|
| F50214D7-F726-4996-9C0C-00021BD681A4 | 3 |
| 4F173E40-54DC-495E-9B84-000B446F09C3 | 3 |
| F9C216CD-0453-434B-AFA0-000C39EFA0FB | 3 |
| 5D09554E-201D-4208-A786-000C537759A1 | 1 |
| F0BDB9A4-E796-4786-8781-000FC60E200C | 4 |
but for an arbitrary number of columns.

Weird ghost records in PostgreSQL - what are they?

I have a very weird issue on our postgresql DB. I have a table called "statement" which has some strange records in it.
Using the command line console psql, I query select * from customer.statement where type in ('QUOTE'); and get 12 rows back. 7 rows look normal, 5 are missing all data except a single column which is a nullable column but seems to hold real values entered by the user. psql tells me that 7 rows were returned even though there are 12. Most of the other columns are not nullable. The weird records look like this:
select * from customer.statement where type = 'QUOTE';
id | issuer_id | recipient_id | recipient_name | recipient_reference | source_statement_id | catalogue_id | reference | issue_date | due_date | description | total | currency | type | tax_level | rounding_mode | status | recall_requested | time_created | time_updated | time_paid
------------------+------------------+------------------+----------------+---------------------+---------------------+--------------+-----------+------------+------------+------------------------------------------------------------------+-----------+----------+-------+-----------+---------------+-----------+------------------+----------------------------+----------------------------+-----------
... 7 valid records removed ...
| | | | | | | | | | Build bulkheads and sheet with plasterboard. +| | | | | | | | | |
| | | | | | | | | | Patch all patches. +| | | | | | | | | |
| | | | | | | | | | Set and sand all joints ready for painting. +| | | | | | | | | |
| | | | | | | | | | Use wall angle on bulkhead in main bedroom. +| | | | | | | | | |
| | | | | | | | | | Build nib and sheet and set in entrance | | | | | | | | | |
(7 rows)
If I run the same query using pgAdmin, I don't see those weird records.
Anyone know what these are?
The plus sign before the separator (+|) indicates a newline character in the displayed string value in psql. So no additional rows, just the same row continued with line breaks. The final line of output in your quote confirms as much: (7 rows).
In pgAdmin you don't see the extra lines as long as you don't increase the height of the field (or copy / paste the content somewhere), but there are multiple lines as well.
Try in psql and in pgAdmin:
test=# SELECT E'This\nis\na\ntest.' AS multi_line, 'foo' AS single_line;
multi_line | single_line
--------------+-------------
This +| foo
is +|
a +|
test. |
(1 row)
The manual about psql:
linestyle
Sets the border line drawing style to one of ascii, old-ascii, or unicode. [...] The default setting is ascii. [...]
ascii style uses plain ASCII characters. Newlines in data are shown using a + symbol in the right-hand margin. [...]

PostgreSQL 9.5 IF-THEN-ELSE inside FUNCTION not available?

My problem
While trying to CREATE a FUNCTION in my PostgreSQL database, version 9.5, I get the following error:
ERROR: syntax error at or near "IF"
LINE 3: IF strpos(trem_outcome, 'VALIDATED') = 0 THEN
Here's the FUNCTION I'm talking about:
CREATE OR REPLACE FUNCTION countValid(outcome text) RETURNS integer AS $$
BEGIN
IF strpos(outcome, 'VALIDATED') = 0 THEN
RETURN 1;
END IF;
RETURN 0;
END
$$ LANGUAGE SQL
Looks like the IF-THEN-ELSE control statements aren't available to me here, although I'm inside a FUNCTION right?
What am I missing?
Some context
I ultimately wanna sum(countValid()) of a huge set of data, like follows:
SELECT
table1.tbl1_pk,
count(table2.tbl2_outcome) as registered,
sum(countValid(table2.tbl2_outcome)) as validated
FROM table1 JOIN table2 ON table2.tbl2_tbl1_fk = table1.tbl1_pk
GROUP BY table1.tbl1_pk;
Where my tables are like:
+---------------------------------------+
| table1 |
+---------------+-----------------------+
| tbl1_pk (int) | tbl1_other_crap (w/e) |
+---------------+-----------------------+
| 1 | ... |
| 2 | ... |
| 3 | ... |
+---------------+-----------------------+
+------------------------------------------------+
| table2 |
+---------+-----------------------+--------------+
| tbl2_pk | tbl2_tbl1_fk | tbl2_outcome |
| (int) | (int -> tbl1.tbl1_pk) | (text) |
+---------+-----------------------+--------------+
| 1 | 1 | VALIDATED |
| 2 | 1 | FLUNKED |
| 3 | 3 | VALIDATED |
| 4 | 3 | VALIDATED |
| 5 | 1 | FLUNKED |
| 6 | 2 | VALIDATED |
| 7 | 3 | VALIDATED |
+---------+-----------------------+--------------+
I'd expect the following result set:
+---------------+------------------+-----------------+
| tbl1_pk (int) | registered (int) | validated (int) |
+---------------+------------------+-----------------+
| 1 | 3 | 1 |
| 2 | 1 | 1 |
| 3 | 3 | 3 |
+---------------+------------------+-----------------+
Minimal reproducible example
I can reproduce my issue on an even simpler function:
CREATE OR REPLACE FUNCTION countValid(outcome text) RETURNS integer AS $$
BEGIN
IF 1 = 1 THEN
RETURN 1;
END IF;
RETURN 0;
END
$$ LANGUAGE SQL
... which triggers:
ERROR: syntax error at or near "IF"
LINE 3: IF 1 = 1 THEN
I'm open to entirely different approaches, although I'd much rather have my work executed in a single query.
You do not need that function. Just use
count(table2.tbl2_outcome = 'VALIDATED' or null)

Can't rename table in RedShift

I run the following command through python3.3 psycopg2 package:
ALTER TABLE my_schema.tbl_old RENAME TO tbl_new
Before the command is run, my python code makes sure tbl_new does not exist.
However, I get the following error:
relation "tbl_new" already exists
Table structure:
bipilot=# select * from PG_TABLE_DEF where tablename='tbl_old';
schemaname | tablename | column | type | encoding | distkey | sortkey | notnull
------------+-----------+--------------+---------------+----------+---------+---------+---------
my_schema | tbl_old | price | numeric(10,2) | lzo | f | 0 | f
my_schema | tbl_old | price_date | date | none | f | 1 | f
my_schema | tbl_old | product_id | smallint | delta | f | 0 | f
No indices are defined.
Also, when I run the same RENAME command from psql shell, it works well.
Anyone can explain this strange behavior?
Thanks!!!
Problem found - bug in my python code - it was written 'tbl_Old' (instead of 'tbl_old').