github.com/ncruces/go-sqlite3@v0.15.1-0.20240520133447-53eef1510ff0/ext/zorder/zorder.go (about) 1 // Package zorder provides functions for z-order transformations. 2 // 3 // https://sqlite.org/src/doc/tip/ext/misc/zorder.c 4 package zorder 5 6 import ( 7 "github.com/ncruces/go-sqlite3" 8 "github.com/ncruces/go-sqlite3/internal/util" 9 ) 10 11 // Register registers the zorder and unzorder SQL functions. 12 func Register(db *sqlite3.Conn) { 13 flags := sqlite3.DETERMINISTIC | sqlite3.INNOCUOUS 14 db.CreateFunction("zorder", -1, flags, zorder) 15 db.CreateFunction("unzorder", 3, flags, unzorder) 16 } 17 18 func zorder(ctx sqlite3.Context, arg ...sqlite3.Value) { 19 var x [63]int64 20 for i := range arg { 21 x[i] = arg[i].Int64() 22 } 23 if len(arg) > len(x) { 24 ctx.ResultError(util.ErrorString("zorder: too many parameters")) 25 return 26 } 27 28 var z int64 29 if len(arg) > 0 { 30 for i := 0; i < 63; i++ { 31 j := i % len(arg) 32 z |= (x[j] & 1) << i 33 x[j] >>= 1 34 } 35 } 36 37 for i := range arg { 38 if x[i] != 0 { 39 ctx.ResultError(util.ErrorString("zorder: parameter too large")) 40 return 41 } 42 } 43 ctx.ResultInt64(z) 44 } 45 46 func unzorder(ctx sqlite3.Context, arg ...sqlite3.Value) { 47 z := arg[0].Int64() 48 n := arg[1].Int64() 49 i := arg[2].Int64() 50 51 var k int 52 var x int64 53 for j := i; j < 63; j += n { 54 x |= ((z >> j) & 1) << k 55 k++ 56 } 57 ctx.ResultInt64(x) 58 }