Dynamic SQL Error – SQL error code = -104 Token unknown happening on "select * from table". Python Firebird

Question:

I seem to be getting an error while trying to dump all the data from the fdb file.

That was the error. ‘BLOB’ is the name of the table

("Error while preparing SQL statement:n- SQLCODE: -104n- Dynamic SQL Errorn- SQL error code = -104n- Token unknown - line 1, column 15n- 'BLOB'", -104, 335544569)

the code


def js(val):
    if type(val) == int:
        return val
    if type(val) == str:
        return val
    if val is None:
        return val
    if type(val) == decimal.Decimal:
        return str(val)
    if type(val) == datetime.datetime:
        return val.isoformat()
    raise Exception(type(val))


con = fdb.connect(dsn='202204.fdb', user='sysdba', password='masterkey')

cur = con.cursor()

cur.execute(
    "SELECT a.RDB$RELATION_NAME FROM RDB$RELATIONS a WHERE RDB$SYSTEM_FLAG=0")


tables = [row[0].strip() for row in cur.fetchall()]

db = {}

for table in tables:
    db[table] = {}
    cur.execute(
        f"select rdb$field_name from rdb$relation_fields where rdb$relation_name='{table}' order by rdb$field_position")

    db[table]['cols'] = [head[0].strip() for head in cur.fetchall()]

    print(db)

    cur.execute(f"select * from '{table}'") # code breaks here

    db[table]['rows'] = [[js(field) for field in row]
                         for row in cur.fetchall()]

the expected structure

{"BLOB": {"cols": ["GUID", "UPDATE", "DATA"], "rows": []}}

Python 3.9
Firebird 2.5

Asked By: Kareem Etefy

||

Answers:

The interpolated string "select * from '{table}'" will not produce a valid query. Things enclosed in single quotes are string literals, and you cannot select from a string literal. If you intended this as a quoted identifier, you should enclose it in double quotes ("), not single quotes (').

That is, right now you produce a statement select * from 'BLOB', which is why the error refers to the unknown token 'BLOB', as Firebird expects a (quoted or unquoted) identifier. Change your code to produce select * from "BLOB".

Also, please be aware that string interpolation like this makes your code vulnerable to SQL injection, although that is less of a problem in this case, as you’re selecting from system tables, there are edge cases with table names which contain a double quote (third query), or a single quote (second query). Your second query should use parameters, not string interpolation (this is not possible for the third).

Answered By: Mark Rotteveel
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.