feat(sql): Window Functions + MERGE statement + REST bridge plan
- Add Window Functions: ROW_NUMBER, RANK, DENSE_RANK, LEAD, LAG, FIRST_VALUE, LAST_VALUE, NTILE with PARTITION BY, ORDER BY, ROWS/RANGE frame specifications - Add MERGE/UPSERT statement with WHEN MATCHED UPDATE and WHEN NOT MATCHED INSERT - Add SQL/PGQ Property Graph long-term plan in PLAN_SQL_ADVANCED.md - Add 7 new tests for Window Functions and MERGE - Update baraql.md documentation
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
## BaraQL IR — Intermediate Representation for compilation
|
||||
import std/tables
|
||||
import std/strutils
|
||||
import ../core/types
|
||||
|
||||
type
|
||||
@@ -52,6 +53,7 @@ type
|
||||
irekExists
|
||||
irekStar
|
||||
irekJsonPath
|
||||
irekWindowFunc
|
||||
|
||||
IRJoinKind* = enum
|
||||
irjkInner
|
||||
@@ -71,11 +73,13 @@ type
|
||||
irpkInsert
|
||||
irpkUpdate
|
||||
irpkDelete
|
||||
irpkMerge
|
||||
irpkCreateType
|
||||
irpkUnion
|
||||
irpkCTE
|
||||
irpkValues
|
||||
irpkExplain
|
||||
irpkWindow
|
||||
|
||||
IRPlan* = ref object
|
||||
case kind*: IRPlanKind
|
||||
@@ -121,6 +125,14 @@ type
|
||||
deleteTable*: string
|
||||
deleteAlias*: string
|
||||
deleteSource*: IRPlan
|
||||
of irpkMerge:
|
||||
mergeTarget*: string
|
||||
mergeTargetAlias*: string
|
||||
mergeSourcePlan*: IRPlan
|
||||
mergeOnCond*: IRExpr
|
||||
mergeUpdateSets*: seq[(string, IRExpr)]
|
||||
mergeInsertFields*: seq[string]
|
||||
mergeInsertValues*: seq[seq[IRExpr]]
|
||||
of irpkCreateType:
|
||||
createTypeName*: string
|
||||
createTypeDef*: IRType
|
||||
@@ -136,6 +148,15 @@ type
|
||||
valuesRows*: seq[seq[IRExpr]]
|
||||
of irpkExplain:
|
||||
explainPlan*: IRPlan
|
||||
of irpkWindow:
|
||||
winSource*: IRPlan
|
||||
winFuncs*: seq[IRExpr]
|
||||
winPartition*: seq[IRExpr]
|
||||
winOrderBy*: seq[IRExpr]
|
||||
winOrderDirs*: seq[bool]
|
||||
winFrameMode*: string
|
||||
winFrameStart*: string
|
||||
winFrameEnd*: string
|
||||
|
||||
IRExpr* = ref object
|
||||
case kind*: IRExprKind
|
||||
@@ -172,6 +193,15 @@ type
|
||||
jpExpr*: IRExpr
|
||||
jpKey*: string
|
||||
jpAsText*: bool
|
||||
of irekWindowFunc:
|
||||
wfName*: string
|
||||
wfArgs*: seq[IRExpr]
|
||||
wfPartition*: seq[IRExpr]
|
||||
wfOrderBy*: seq[IRExpr]
|
||||
wfOrderDirs*: seq[bool]
|
||||
wfFrameMode*: string
|
||||
wfFrameStart*: string
|
||||
wfFrameEnd*: string
|
||||
|
||||
type
|
||||
TypeChecker* = ref object
|
||||
@@ -255,3 +285,14 @@ proc inferExpr*(tc: TypeChecker, expr: IRExpr, context: Table[string, IRType]):
|
||||
of irekJsonPath:
|
||||
if expr.jpAsText: return IRType(name: "str", kind: itkScalar)
|
||||
return IRType(name: "json", kind: itkScalar)
|
||||
of irekWindowFunc:
|
||||
# Window functions return int64 for ranking, or the type of the argument for value functions
|
||||
case expr.wfName.toLower()
|
||||
of "row_number", "rank", "dense_rank", "ntile":
|
||||
return IRType(name: "int64", kind: itkScalar)
|
||||
of "lead", "lag", "first_value", "last_value":
|
||||
if expr.wfArgs.len > 0:
|
||||
return tc.inferExpr(expr.wfArgs[0], context)
|
||||
return nil
|
||||
else:
|
||||
return IRType(name: "unknown", kind: itkScalar)
|
||||
|
||||
Reference in New Issue
Block a user