[TIP] Protection from SQL Injection Attack.

This tip is expired by article two-steps-forward-to-more-secure-applications. The First part of the article discusses  SQL Injection Attack and how to develop code protected from it.

After read of the article you will know that to easy way for protection – is usage of SQL binding. Wow? One more reason to ALWAYS use SQL binding!  Other well known reason are

  • reduces CPU time as for client so for server, because no string concatenations on the client side, and less job for parser on the server side.
  • enables usage of Query Pool, because SQL command is the same byte to byte.

Altering ObjectPtr

ObjectPtr field contains RecID values of some “target” table. If you need to change ObjectPtr in order to point another table those values are not valid anymore – so default behavior is to nullify them.  But sometime it looks to be too strong. For instance – changing  field or link name or on-delete policy should not cause such data zeroing.

There are two ways to keep existed values altering ObjectPtr:

  1. There is a global property – OnChangeTypeZeroPtr. It is set to true by default. But you may change it with following statement – “SET PROPERTY OnChangeTypeZeroPtr TO false”. After this altering ObjectPtr will prevent zeroing data (sure it will be nulls for records which are absent in the new target table).  This property is not “schema-storable” – so you should set it up on each run if you need it.
  2. The first approach is a global setting – so you will be able to keep some ObjectPtr values even changing “target” table. So we implement one more way – much more simple because the only thing you should keep in your mind is – the values will be preserved until you touch “target table” ObjectPtr property (because all values will be valid for the same target anyway).

[NEW] REGEX_REPLACE() function.

In 4.5.1 release we have add a new REGEX_REPLACE() function  to Valentina Expresions, which can be used in Table Methods, SQL and therefore, in Reports.

Up to now, we was able to do searches with the help of REGEX operator:

… WHERE fld REGEX ‘ab.[cdf]*’

New function brings the awesome power of REGEX to manipulate by strings stored in the database! Now we can not only search using REGEX, but modify strings! You can do that in the

  • SELECT EXPR, …
  • UPDATE TABLE T SET fld = EXPR

where EXPR is REGEX_REPLACE() function or contains it as a part.

Read details about this function here.

Internal optimization for views and sub-queries.

In some cases we can avoid copying sub-query result to the temporary table. We can even use sub-query cursor “as is” – so it could be used as a result of the whole query. In other words there  is almost zero overhead against a simple query.

For now such optimization can be applied if a query:

  1. contains only “*” item in the select list clause
  2. has no “where” clause
  3. has no “group by” clause
  4. has no “having” clause
  5. has no “distinct” clause
  6. is not a part of some join operation
  7. has no “order by” clause
  8. has no binding values
  9. sub-query is not a “union/except/intersect” result

Examples:

SELECT * FROM (SELECT * FROM t1 WHERE f1 > 5);

SELECT * FROM (SELECT t1.f1, t2 f1 FROM t1 JOIN t2 ON l1 WHERE t1.f1 > 5 AND t2.f1 <3);

Valentina SQL get powerful FORMAT() function.

Ivan have add into Valentina engine new very powerful FORMAT() function for SQL.

It provides great ability to convert numbers and date/times into string format.

Please read detailed syntax in the Valentina WIKI:
http://valentina-db.com/dokuwiki/doku.php?id=valentina:vcomponents:vsql:reference:expr:funcs_string#format

The same algorithms will be added in nearest time to Valentina Reports.

Improvements for stored procedures and binded queries

It was a huge improvement to solve the problem with a “second run” in stored procedures and binded queries.  Sometimes there was an incorrect behavior because of “over-prepared” nodes. There was a workaround with “EXECUTE” statement (which is actually developed  to prepare any SQL statement and execute one from another SQL statement). So now this workaround could be omitted.

Hierarchical (Recursive) Queries in Valentina SQL

There are three new kind of queries specially designed  for recursive (hierarchical) tables.

Such kind of tables are widely used. It could be human relationships, threaded forums and anything which might be described as tree-like data.

There are few common SQL ways to operate with such structures but all of them are too far from perfect.

Valentina introduces special kind of query which looks much more clear, natural and readable.

Syntax:
vext_recursive_table         -- v4.1
    :   {ANCESTORS | BROTHERS | DESCENDANTS} OF vext_root_objects
        [{TO|ON} LEVEL UINT] USING link_name [WITH {ROOT | ROOTS}]

vext_root_objects
    :   UINT
    |   variable_name
    |   ( search_condition )

Examples:

ANCESTORS OF (RecID IN(4,5)) ON LEVEL 1 USING l1
BROTHERS OF 4 ON LEVEL 2 USING l1
SELECT * FROM (ANCESTORS OF (RecID IN(4,5)) ON LEVEL 1 USING l1)  WHERE f1 = 'Branch2'

See also:

* WIKI: Valentina SQL Reference: Hierarchical (Recursive) Queries for description of exact syntax of these commands and examples.

* WIKI: Article Hierarchical (Recursive) Queries in Valentina SQL