1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00
samba-mirror/libcli/wsp/wsp_aqs_lexer.l
Noel Power b28fb85a1f libcli/wsp: Add support for simplified Advanced Query Syntax
Add support to parse AQS-like (Advanced query syntax)

AQS - see https://learn.microsoft.com/en-gb/windows/win32/search/-search-3x-advancedquerysyntax

The basic (AQS) syntax is supported e.g. a query is built of a sequence of
queries connected by AND, OR and NOT where the query elements are
essentially restrictions defined by a property. There are some
limitations on the operators supported[1] and additionally some things
like enumerated ranges are not supported at all and range values are not
delimited as specified [2]. Some special cases that you see in the
windows search UI are exceptions [3] which are handled more or less as keywords

Some examples:

The following are all exactly the same query just expressed using
different variations of the syntax

'ALL:($<p403 OR $<p404) AND System.Kind:picture AND Scope:"FILE://somemachine/someshare" AND > System.Size:10241-102401'

'ALL:$<p403 OR ALL:$<p404 AND System.Kind:picture AND Scope:"FILE://somemachine/someshare" AND > System.Size:>=10241 AND System.Size:<102401'

'ALL:$<p403 OR ALL:$<p404 AND System.Kind:picture AND Scope:"FILE://somemachine/someshare" AND > System.Size:small'

The queries above by default select the property System.ItemUrl as the
one and only column returned, the query parameter however accepts a
variation to the AQS like syntax to allow arbitrary columns to be
selected e.g.

'SELECT System.ItemName, System.ItemURL, System.Size WHERE ALL:$<p403 OR ALL:$<p404 AND System.Kind:picture AND Scope:"FILE://somemachine/someshare" AND System.Size:small'

[1] supported operators
    -------------------
    =    Equals
    !=   Not Equals
    >    Greater than
    <    Less than
    >=   Greater than or equals
    <=   Less than or equals

    $=   equals
    $<   starts with
[2] ranges are specified as value-value instead of value..value (seems
    my flex/bison skills are not good enough and couldn't get that to
    work with '..'

[3] The windows UI has shortcut ranges (presumably represented as enumerated
    ranges) providing date ranges like 'today', 'tomorrow',
   'lastweek' etc. and similarly sizes like "empty, tiny, small, large..."

   These are supported (but implemented as keywords)

Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2023-10-25 22:23:38 +00:00

153 lines
3.4 KiB
Plaintext

/*
* Unix SMB/CIFS implementation.
*
* Window Search Service
*
* Copyright (c) Noel Power
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
%{
#include "includes.h"
#include "libcli/wsp/wsp_aqs.h"
#include "libcli/wsp/wsp_aqs_parser.tab.h"
#include <stdio.h>
#define YY_NO_INPUT
%}
%option warn nodefault nounput
%option reentrant noyywrap never-interactive nounistd
%option bison-bridge
LPAREN "("
RPAREN ")"
AND "AND"
OR "OR"
NOT "NOT"
EQ "=="
NE "!="
GE ">="
LE "<="
LESS "<"
GREATER ">"
COMMA ","
WHERE "WHERE"
SELECT "SELECT"
PROP_EQUALS ":"
TRUE "true"
FALSE "false"
TODAY "today"
YESTERDAY "yesterday"
THISWEEK "thisweek"
LASTWEEK "lastweek"
THISMONTH "thismonth"
LASTMONTH "lastmonth"
THISYEAR "thisyear"
LASTYEAR "lastyear"
EMPTY "empty"
TINY "tiny"
SMALL "small"
MEDIUM "medium"
LARGE "large"
HUGE "huge"
GIGANTIC "gigantic"
STARTS_WITH "$<"
EQUALS "$="
K "K"
M "M"
G "G"
T "T"
KB "KB"
MB "MB"
GB "GB"
TB "TB"
RANGE "-"
NUMBER [0-9]+
WS [ \r\n\t]*
IDENTIFIER [a-z\."A-Z_][a-z\."A-Z_0-9]*
STRING_LITERAL L?\"(\\.|[^\\"])*\"
%%
{WS} { /* Skip blanks. */ }
{NUMBER} { sscanf(yytext, "%"PRId64, &yylval->num); return TOKEN_NUMBER; }
{AND} { return TOKEN_AND; }
{OR} { return TOKEN_OR; }
{NOT} { return TOKEN_NOT; }
{EQ} { return TOKEN_EQ; }
{NE} { return TOKEN_NE; }
{GE} { return TOKEN_GE; }
{LE} { return TOKEN_LE; }
{LESS} { return TOKEN_LT; }
{GREATER} { return TOKEN_GT; }
{LPAREN} { return TOKEN_LPAREN; }
{RPAREN} { return TOKEN_RPAREN; }
{COMMA} { return TOKEN_COMMA; }
{WHERE} { return TOKEN_WHERE; }
{SELECT} { return TOKEN_SELECT; }
{TRUE} { return TOKEN_TRUE; }
{FALSE} { return TOKEN_FALSE; }
{PROP_EQUALS} { return TOKEN_PROP_EQUALS; }
{STARTS_WITH} { return TOKEN_STARTS_WITH;}
{EQUALS} { return TOKEN_EQUALS;}
{K} { return TOKEN_K; }
{M} { return TOKEN_M; }
{G} { return TOKEN_G; }
{T} { return TOKEN_T; }
{KB} { return TOKEN_KB; }
{MB} { return TOKEN_MB; }
{GB} { return TOKEN_GB; }
{TB} { return TOKEN_TB; }
{RANGE} { return TOKEN_RANGE; }
{TODAY} { return TOKEN_TODAY; }
{YESTERDAY} { return TOKEN_YESTERDAY;}
{THISWEEK} { return TOKEN_THISWEEK;}
{LASTWEEK} { return TOKEN_LASTWEEK;}
{THISMONTH} { return TOKEN_THISMONTH; }
{LASTMONTH} { return TOKEN_LASTMONTH; }
{THISYEAR} { return TOKEN_THISYEAR; }
{LASTYEAR} { return TOKEN_LASTYEAR; }
{EMPTY} { return TOKEN_EMPTY; }
{TINY} { return TOKEN_TINY; }
{SMALL} { return TOKEN_SMALL; }
{MEDIUM} { return TOKEN_MEDIUM; }
{LARGE} { return TOKEN_LARGE; }
{HUGE} { return TOKEN_HUGE; }
{GIGANTIC} { return TOKEN_GIGANTIC; }
{STRING_LITERAL} { yylval->strval = talloc_asprintf(talloc_tos(), "%s", yytext); return TOKEN_STRING_LITERAL; }
{IDENTIFIER} { yylval->strval = talloc_asprintf(talloc_tos(), "%s", yytext); return TOKEN_IDENTIFIER; }
. { }
%%