| Crates.io | orql |
| lib.rs | orql |
| version | 0.1.0 |
| created_at | 2026-01-12 20:14:27.680631+00 |
| updated_at | 2026-01-12 20:14:27.680631+00 |
| description | A toy SQL parser for a subset of the Oracle dialect. |
| homepage | |
| repository | https://codeberg.org/xitep/orql.git |
| max_upload_size | |
| id | 2038766 |
| size | 727,763 |
A toy SQL parser for a subset of the Oracle dialect.
The motivation for parser is to parse Oracle SQL statements into as an Abstract Syntax Tree while allowing the complete reconstruction of the orignally parsed source code. Therefore, the parser tries to preserve and expose token location as well as comments.
At the same time, the challenge is to not pay additional costs when not being interested in token location information and/or comments.
let sql = "select * from dual";
let stmts = parser::parse(sql).expect("bad sql!");
for stmt in stmts {
println!("{:#?}", stmt);
}
Advanced examples demo'ing access to locations and comments can be found in the rustdoc of the individual, public modules.
simple_expressioncompound_expression
PRIOR ...COLLATE ...av_meas_expressioncase_expressioncursor_expressiondatetime_expressionfunction_expressioninterval_expressionJSON_object_access_expressionmodel_expressionobject_access_expresionscalar_subquery_expressiontype_constructor_expressionplaceholder_expression
INDICATOR ...f(arg0 => 1, arg1 => 2)
countDISTINCT, UNIQUE, ALL keywords before the first argumentWITHIN GROUPOVER clauseKEEP FIRST | LAST* marks functions with dedicated / extended syntax clauses)
ABSACOSADD_MONTHSANY_VALUEAPPROX_COUNT*APPROX_COUNT_DISTINCTAPPROX_COUNT_DISTINCT_AGGAPPROX_COUNT_DISTINCT_DETAILAPPROX_MEDIAN*APPROX_PERCENTILE*APPROX_PERCENTILE_AGGAPPROX_PERCENTILE_DETAIL*APPROX_RANK*APPROX_SUM*ASCIIASCIISTRASINATANATAN2AVG*BFILENAMEBIN_TO_NUMBITANDBIT_AND_AGGBITMAP_BIT_POSITIONBITMAP_BUCKET_NUMBERBITMAP_CONSTRUCT_AGGBITMAP_COUNTBITMAP_OR_AGGBIT_OR_AGGBIT_XOR_AGGCARDINALITYCAST*CEILCHARTOROWIDchecksum*CHR*CLUSTER_DETAILS*CLUSTER_DISTANCE*CLUSTER_ID*CLUSTER_PROBABILITY*CLUSTER_SET*COALESCECOLLATIONCOLLECT*COMPOSECON_DBID_TO_IDCON_GUID_TO_IDcon_id_to_con_namecon_id_to_dbidcon_id_to_guidcon_id_to_uidCON_NAME_TO_IDCON_UID_TO_IDCONCATCONVERTCORR*CORR_ACOSCOSHCOUNT*COVAR_POP*COVAR_SAMP*CUBE_TABLECUME_DIST*CURRENT_DATECURRENT_TIMESTAMPCVDATAOBJ_TO_MAT_PARTITIONDATAOBJ_TO_PARTITIONDBTIMEZONEDECODEDECOMPOSEDENSE_RANK*DEPTHDEREFDUMPEMPTY_BLOB-EMPTY_CLOBEXISTSNODEEXPEXTRACT-datetime*EXTRACT-XMLEXTRACTVALUEFEATURE_COMPARE*FEATURE_DETAILS*FEATURE_ID*FEATURE_SETFEATURE_VALUE*FIRST*FIRST_VALUE*FLOORFROM_TZGREATESTGROUP_IDGROUPINGGROUPING_IDHEXTORAWINITCAPINSTRITERATION_NUMBERJSON_ARRAY*JSON_ARRAYAGG*JSON_DATAGUIDEJSON_MERGEPATCH*JSON_OBJECT*JSON_OBJECTAGG*JSON_QUERY*json_scalar*JSON_SERIALIZE*JSON_TABLE*JSON_TRANSFORMJSON_VALUE*json-type-constructorKURTOSIS_POPKURTOSIS_SAMPLAG*LAST*LAST_DAYLAST_VALUE*LEAD*LEASTLENGTHLISTAGG*LNLNNVL*LOCALTIMESTAMPLOGLOWERLPADLTRIMMAKE_REFMAX*MEDIAN*MIN*MODMONTHS_BETWEENNANVLNCHRNEW_TIMENEXT_DAYNLS_CHARSET_DECL_LENNLS_CHARSET_IDNLS_CHARSET_NAMENLS_COLLATION_IDNLS_COLLATION_NAMENLS_INITCAPNLS_LOWERNLS_UPPERNLSSORTNTH_VALUE*NTILE*NULLIFNUMTODSINTERVALNUMTOYMINTERVALNVLNVL2ORA_DM_PARTITION_NAME*ORA_DST_AFFECTEDORA_DST_CONVERTORA_DST_ERRORORA_HASHORA_INVOKING_USERORA_INVOKING_USERIDPATHPERCENT_RANK*PERCENTILE_CONT*PERCENTILE_DISC*POWERPOWERMULTISETPOWERMULTISET_BY_CARDINALITYPREDICTION*PREDICTION_BOUNDS*PREDICTION_COST*PREDICTION_DETAILS*PREDICTION_PROBABILITY*PREDICTION_SET*PRESENTNNVPRESENTVPREVIOUSRANK*RATIO_TO_REPORT*RAWTOHEXRAWTONHEXREFREFTOHEXREGEXP_COUNTREGEXP_INSTRREGEXP_REPLACEREGEXP_SUBSTRREGR_-Linear-Regression-Functions*REMAINDERREPLACEROUND-dateROUND-numberROUND_TIES_TO_EVEN-numberROW_NUMBER*ROWIDTOCHARROWIDTONCHARRPADRTRIMSCN_TO_TIMESTAMPSESSIONTIMEZONESETSIGNSINSINHSKEWNESS_POP*SKEWNESS_SAMP*SOUNDEXSQRTSTANDARD_HASHSTATS_BINOMIAL_TESTSTATS_CROSSTABSTATS_F_TESTSTATS_KS_TESTSTATS_MODESTATS_MW_TESTSTATS_ONE_WAY_ANOVASTATS_T_TEST_STATS_WSR_TESTSTDDEVSTDDEV_POPSTDDEV_SAMPSUBSTRSUMSYS_CONNECT_BY_PATHSYS_CONTEXTSYS_DBURIGENSYS_EXTRACT_UTCSYS_GUIDSYS_OP_ZONE_IDSYS_TYPEIDSYS_XMLAGGSYS_XMLGENSYSDATESYSTIMESTAMPTANTANHTIMESTAMP_TO_SCNTO_APPROX_COUNT_DISTINCTTO_APPROX_PERCENTILETO_BINARY_DOUBLE*TO_BINARY_FLOAT*TO_BLOB-bfileTO_BLOB-rawTO_CHAR-bfile-blobTO_CHAR-characterTO_CHAR-datetimeTO_CHAR-numberTO_CLOB-bfile-blobTO_CLOB-characterTO_DATE*TO_DSINTERVAL*TO_LOBTO_MULTI_BYTETO_NCHAR-characterTO_NCHAR-datetimeTO_NCHAR-numberTO_NCLOBTO_NUMBER*TO_SINGLE_BYTETO_TIMESTAMP*TO_TIMESTAMP_TZ*TO_UTC_TIMESTAMP_TZTO_YMINTERVAL*TRANSLATETRANSLATE-USINGTREAT*TRIM*TRUNC-dateTRUNC-numberTZ_OFFSET*UIDUNISTRUPPERUSERUSERENVVALIDATE_CONVERSION*VALUEVAR_POPVAR_SAMPVARIANCEVSIZEWIDTH_BUCKETXMLAGG*XMLCAST*XMLCDATAXMLCOLATTVAL*XMLCOMMENTXMLCONCATXMLDIFFXMLELEMENT*XMLEXISTS*XMLFOREST*XMLISVALIDXMLPARSE*XMLPATCHXMLPI*XMLQUERY*XMLSEQUENCEXMLSERIALIZE*XMLTABLE*XMLTRANSFORMSELECT — mostly covered
CONNECT_BYmodel_clausewindow_clauseMERGEUPDATEINSERTDELETESQL syntax noted next is not supported by design:
Example:
select *
from (select 1 as alpha, 'alpha' as name from dual) a
left join (select 1 as beta, 'beta' as name from dual) b
join (select 1 as gamma, 'gamma' as name from dual) c
on 1=1 -- causes `b` and `c` to be joined first ...
on 1=1 -- ... on then this gets evaluated over of the previous inner join with `a`
;
Explanation: https://www.sqlservercentral.com/forums/topic/multiple-on-clauses-in-one-join
datafusion-sqlparser-rs
— A mature and complete SQL parser covering the full ANSI/ISO SQL Standard
with support for database product specific extensions. Its exposed AST is
general purpose — a union of all supported dialect specific features. Since
sqlparser's AST doesn't contain nodes for every token in the parsed SQL,
it's difficult to reconstruct the originally parsed SQL with regards to
possible comments and indentation.