pg_scanner - patch no.1 - Mailing list pgadmin-hackers

From Vladimir Kokovic
Subject pg_scanner - patch no.1
Date
Msg-id CAHsHPqckwX=zZ0mjBqcp3SDpN7xnejgz+ha17PpDXj4BcKubKQ@mail.gmail.com
Whole thread Raw
Responses Re: pg_scanner - patch no.1  (Dave Page <dpage@pgadmin.org>)
Re: pg_scanner - patch no.1  (Dave Page <dpage@pgadmin.org>)
List pgadmin-hackers
Hi,

This patch is my try to add lexical scanner for PostgreSQL SQL
commands in Pgadmin source tree(prerequisite for patches no.2 and 3).

The main reason why that is done is to scan and parse a SQL command in
the same way
 like PostgreSQL server, but for limited number of parse functions.

All scanner special cases are covered: TYPECAST(::), COLON_EQUALS(:=),
DOT_DOT(..) and $foo$.

Currently, three parsers implemented:

1. parse SQL command string for commands separated by ';'
      returns single linked list of commands
      struct myScannerNode *get_all_commands_cpp(const struct
myScannerNode *head);

2. parse RULE SQL command and substitute source schema with target schema
      returns CREATE RULE SQL command with new schema name
      char *parse_rule_cpp(const struct myScannerNode *head, const
char *rulename, const char *targetschema, const char *tablename);

3. parse TRIGGER SQL command and substitute source schema with target
schema (pgadmin/utils/pasteTables.cpp)
      returns CREATE TRIGGER SQL command with new schema name
      char *parse_trigger_cpp(const struct myScannerNode *head, const
char *targetschema);


For all parsers 'scan_SQL_cpp' method is prerequisite which scan SQL
command for tokens:
    returns single linked list of scan results (tokens)
    struct myScannerNode *scan_SQL_cpp(const char *command);

If some error occurred during scan process, variable
'pgadmin_scanner_last_error' contains diagnostic message.


*** This code snippet is from my pgadmin/frm/frmQuery.cpp ***

/*
 * The scanner returns extra data about scanned tokens in this union type.
 * Note that this is a subset of the fields used in YYSTYPE of the bison
 * parsers built atop the scanner.
 */
typedef union core_YYSTYPE
{
    int            ival;            /* for integer literals */
    char       *str;            /* for identifiers and non-integer literals */
    const char *keyword;        /* canonical spelling of keywords */
} core_YYSTYPE;


/*
    my token data struct
*/
struct myScannerData {
    int loc;
    int token;
    core_YYSTYPE val;
};


/*
    my single linked list for scan results
*/
struct myScannerNode {
    struct myScannerData data;
    struct myScannerNode *next;
};


//command offest from the beginning of SQL command string for each SQL command
wxArrayInt locs;

//SQL commands (queries)
wxArrayString    queries;

//this is the first step which must be executed
//scan_SQL_cpp returns single linked list of scan results (tokens)

struct myScannerNode *head = scan_SQL_cpp(query.ToUTF8());
if (head)
{
//parse scan results
//get_all_commands_cpp returns single linked list of commands
    struct myScannerNode *result = get_all_commands_cpp(head);

    struct myScannerNode *current = result;
    if (current)
    {
        do
        {
            wxString x = wxString(current->data.val.str, wxConvUTF8);
            queries.Add(x);
            locs.Add(current->data.loc);
            current = current->next;
        } while (current != result);
        destroylist(result);
    }
    destroylist(head);
}



*** This code snippet is from my pgadmin/utils/pasteTables.cpp ***

    struct myScannerNode *head =
scan_SQL_cpp(definition.mb_str(*srcrule->GetConnection()->GetConv()));
    if (head)
    {
        char *rule = parse_rule_cpp(
            head, qtname.ToAscii(), targetschema->GetIdentifier().ToAscii(),
newtablename.ToAscii());
        if (rule)
        {
            newdefinition = wxString(rule, *targetschema->GetConnection()->GetConv());
            free(rule);
        }
        destroylist_cpp(head);
    }


Best regards
Vladimir Kokovic
Belgrade, Serbia, 21.October 2012

Attachment

pgadmin-hackers by date:

Previous
From: Vladimir Kokovic
Date:
Subject: copy/paste table(s) - patch no.3
Next
From: Dave Page
Date:
Subject: pgAdmin III commit: Fix a potential crash in the FTS config dialog.